From fc37cc4a02ed13d1a73b941a9f80975600fd1b99 Mon Sep 17 00:00:00 2001 From: David Foerster Date: Tue, 10 May 2016 20:20:14 +0200 Subject: Normalize all line terminators --- src/Boot/Windows/Bios.h | 64 +- src/Boot/Windows/Boot.vcproj | 492 +++---- src/Boot/Windows/BootCommon.h | 164 +-- src/Boot/Windows/BootConfig.cpp | 204 +-- src/Boot/Windows/BootConfig.h | 92 +- src/Boot/Windows/BootConsoleIo.cpp | 678 ++++----- src/Boot/Windows/BootConsoleIo.h | 144 +- src/Boot/Windows/BootCrt.asm | 54 +- src/Boot/Windows/BootDebug.cpp | 362 ++--- src/Boot/Windows/BootDebug.h | 120 +- src/Boot/Windows/BootDefs.h | 398 +++--- src/Boot/Windows/BootDiskIo.cpp | 982 ++++++------- src/Boot/Windows/BootDiskIo.h | 240 ++-- src/Boot/Windows/BootEncryptedIo.cpp | 264 ++-- src/Boot/Windows/BootEncryptedIo.h | 44 +- src/Boot/Windows/BootMain.cpp | 2538 +++++++++++++++++----------------- src/Boot/Windows/BootMain.h | 68 +- src/Boot/Windows/BootMemory.cpp | 172 +-- src/Boot/Windows/BootMemory.h | 56 +- src/Boot/Windows/BootSector.asm | 488 +++---- src/Boot/Windows/BootStrings.h | 40 +- src/Boot/Windows/Decompressor.c | 130 +- src/Boot/Windows/IntFilter.cpp | 1290 ++++++++--------- src/Boot/Windows/IntFilter.h | 40 +- src/Boot/Windows/Makefile | 404 +++--- src/Boot/Windows/Platform.cpp | 460 +++--- src/Boot/Windows/Platform.h | 232 ++-- 27 files changed, 5110 insertions(+), 5110 deletions(-) (limited to 'src/Boot/Windows') diff --git a/src/Boot/Windows/Bios.h b/src/Boot/Windows/Bios.h index 314b1a62..dd2da6be 100644 --- a/src/Boot/Windows/Bios.h +++ b/src/Boot/Windows/Bios.h @@ -1,32 +1,32 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_Bios -#define TC_HEADER_Boot_Bios - -#include "Platform.h" - -#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9 - -#define TC_FIRST_BIOS_DRIVE 0x80 -#define TC_LAST_BIOS_DRIVE 0x8f -#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1) - -enum -{ - BiosResultSuccess = 0x00, - BiosResultInvalidFunction = 0x01 -}; - -typedef byte BiosResult; - -#endif // TC_HEADER_Boot_Bios +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_Bios +#define TC_HEADER_Boot_Bios + +#include "Platform.h" + +#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9 + +#define TC_FIRST_BIOS_DRIVE 0x80 +#define TC_LAST_BIOS_DRIVE 0x8f +#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1) + +enum +{ + BiosResultSuccess = 0x00, + BiosResultInvalidFunction = 0x01 +}; + +typedef byte BiosResult; + +#endif // TC_HEADER_Boot_Bios diff --git a/src/Boot/Windows/Boot.vcproj b/src/Boot/Windows/Boot.vcproj index d0b40f1a..64ad48ec 100644 --- a/src/Boot/Windows/Boot.vcproj +++ b/src/Boot/Windows/Boot.vcproj @@ -1,246 +1,246 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Boot/Windows/BootCommon.h b/src/Boot/Windows/BootCommon.h index 4d91981b..1dc86560 100644 --- a/src/Boot/Windows/BootCommon.h +++ b/src/Boot/Windows/BootCommon.h @@ -1,82 +1,82 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootCommon -#define TC_HEADER_Boot_BootCommon - -#include "Common/Password.h" -#include "BootDefs.h" - -// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version -#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0117 - -#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) - -#define TC_BOOT_VOLUME_HEADER_SECTOR (TC_BOOT_LOADER_AREA_SECTOR_COUNT - 1) -#define TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET (TC_BOOT_VOLUME_HEADER_SECTOR * TC_SECTOR_SIZE_BIOS) - -#define TC_CD_BOOTSECTOR_OFFSET 0xd000 -#define TC_CD_BOOT_LOADER_SECTOR 26 - -#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR TC_BOOT_LOADER_AREA_SECTOR_COUNT -#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR * TC_SECTOR_SIZE_BIOS) - -#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR + TC_BOOT_LOADER_AREA_SECTOR_COUNT) -#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET (TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR * TC_SECTOR_SIZE_BIOS) - -#define TC_MBR_SECTOR 0 -#define TC_MAX_MBR_BOOT_CODE_SIZE 440 - -#define TC_MAX_EXTRA_BOOT_PARTITION_SIZE (512UL * 1024UL * 1024UL) - - -#pragma pack (1) - -typedef struct -{ - byte Flags; -} BootSectorConfiguration; - - -// Modifying this value can introduce incompatibility with previous versions -#define TC_BOOT_LOADER_ARGS_OFFSET 0x10 - -typedef struct -{ - // Modifying this structure can introduce incompatibility with previous versions - char Signature[8]; - uint16 BootLoaderVersion; - uint16 CryptoInfoOffset; - uint16 CryptoInfoLength; - uint32 HeaderSaltCrc32; - Password BootPassword; - uint64 HiddenSystemPartitionStart; - uint64 DecoySystemPartitionStart; - uint32 Flags; - uint32 BootDriveSignature; - - uint32 BootArgumentsCrc32; - -} BootArguments; - -// Modifying these values can introduce incompatibility with previous versions -#define TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION 0x1 - -#pragma pack () - -// Boot arguments signature should not be defined as a static string -// Modifying these values can introduce incompatibility with previous versions -#define TC_SET_BOOT_ARGUMENTS_SIGNATURE(SG) do { SG[0] = 'T'; SG[1] = 'R'; SG[2] = 'U'; SG[3] = 'E'; SG[4] = 0x11; SG[5] = 0x23; SG[6] = 0x45; SG[7] = 0x66; } while (FALSE) -#define TC_IS_BOOT_ARGUMENTS_SIGNATURE(SG) (SG[0] == 'T' && SG[1] == 'R' && SG[2] == 'U' && SG[3] == 'E' && SG[4] == 0x11 && SG[5] == 0x23 && SG[6] == 0x45 && SG[7] == 0x66) - - -#endif // TC_HEADER_Boot_BootCommon +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootCommon +#define TC_HEADER_Boot_BootCommon + +#include "Common/Password.h" +#include "BootDefs.h" + +// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version +#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0117 + +#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) + +#define TC_BOOT_VOLUME_HEADER_SECTOR (TC_BOOT_LOADER_AREA_SECTOR_COUNT - 1) +#define TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET (TC_BOOT_VOLUME_HEADER_SECTOR * TC_SECTOR_SIZE_BIOS) + +#define TC_CD_BOOTSECTOR_OFFSET 0xd000 +#define TC_CD_BOOT_LOADER_SECTOR 26 + +#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR TC_BOOT_LOADER_AREA_SECTOR_COUNT +#define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR * TC_SECTOR_SIZE_BIOS) + +#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR + TC_BOOT_LOADER_AREA_SECTOR_COUNT) +#define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET (TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR * TC_SECTOR_SIZE_BIOS) + +#define TC_MBR_SECTOR 0 +#define TC_MAX_MBR_BOOT_CODE_SIZE 440 + +#define TC_MAX_EXTRA_BOOT_PARTITION_SIZE (512UL * 1024UL * 1024UL) + + +#pragma pack (1) + +typedef struct +{ + byte Flags; +} BootSectorConfiguration; + + +// Modifying this value can introduce incompatibility with previous versions +#define TC_BOOT_LOADER_ARGS_OFFSET 0x10 + +typedef struct +{ + // Modifying this structure can introduce incompatibility with previous versions + char Signature[8]; + uint16 BootLoaderVersion; + uint16 CryptoInfoOffset; + uint16 CryptoInfoLength; + uint32 HeaderSaltCrc32; + Password BootPassword; + uint64 HiddenSystemPartitionStart; + uint64 DecoySystemPartitionStart; + uint32 Flags; + uint32 BootDriveSignature; + + uint32 BootArgumentsCrc32; + +} BootArguments; + +// Modifying these values can introduce incompatibility with previous versions +#define TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION 0x1 + +#pragma pack () + +// Boot arguments signature should not be defined as a static string +// Modifying these values can introduce incompatibility with previous versions +#define TC_SET_BOOT_ARGUMENTS_SIGNATURE(SG) do { SG[0] = 'T'; SG[1] = 'R'; SG[2] = 'U'; SG[3] = 'E'; SG[4] = 0x11; SG[5] = 0x23; SG[6] = 0x45; SG[7] = 0x66; } while (FALSE) +#define TC_IS_BOOT_ARGUMENTS_SIGNATURE(SG) (SG[0] == 'T' && SG[1] == 'R' && SG[2] == 'U' && SG[3] == 'E' && SG[4] == 0x11 && SG[5] == 0x23 && SG[6] == 0x45 && SG[7] == 0x66) + + +#endif // TC_HEADER_Boot_BootCommon diff --git a/src/Boot/Windows/BootConfig.cpp b/src/Boot/Windows/BootConfig.cpp index 63ebaf5e..75baf19e 100644 --- a/src/Boot/Windows/BootConfig.cpp +++ b/src/Boot/Windows/BootConfig.cpp @@ -1,102 +1,102 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "BootConfig.h" - -byte BootSectorFlags; - -byte BootLoaderDrive; -byte BootDrive; -bool BootDriveGeometryValid = false; -bool PreventNormalSystemBoot = false; -bool PreventBootMenu = false; -char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; -uint32 OuterVolumeBackupHeaderCrc; - -bool BootStarted = false; - -DriveGeometry BootDriveGeometry; - -CRYPTO_INFO *BootCryptoInfo; -Partition EncryptedVirtualPartition; - -Partition ActivePartition; -Partition PartitionFollowingActive; -bool ExtraBootPartitionPresent = false; -uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage -uint64 HiddenVolumeStartSector; - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - -void ReadBootSectorUserConfiguration () -{ - byte userConfig; - - AcquireSectorBuffer(); - - if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess) - goto ret; - - userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; - -#ifdef TC_WINDOWS_BOOT_AES - EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION)); -#endif - - PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC); - - memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); - CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0; - - if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE) - { - if (CustomUserMessage[0]) - { - InitVideoMode(); - Print (CustomUserMessage); - } - - DisableScreenOutput(); - } - - if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM) - { - PimValueOrHiddenVolumeStartUnitNo.LowPart = 0; - memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE); - } - else - PimValueOrHiddenVolumeStartUnitNo.LowPart = -1; - - OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET); - -ret: - ReleaseSectorBuffer(); -} - - -BiosResult UpdateBootSectorConfiguration (byte drive) -{ - AcquireSectorBuffer(); - - BiosResult result = ReadWriteMBR (false, drive); - if (result != BiosResultSuccess) - goto ret; - - SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags; - result = ReadWriteMBR (true, drive); - -ret: - ReleaseSectorBuffer(); - return result; -} - -#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "BootConfig.h" + +byte BootSectorFlags; + +byte BootLoaderDrive; +byte BootDrive; +bool BootDriveGeometryValid = false; +bool PreventNormalSystemBoot = false; +bool PreventBootMenu = false; +char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; +uint32 OuterVolumeBackupHeaderCrc; + +bool BootStarted = false; + +DriveGeometry BootDriveGeometry; + +CRYPTO_INFO *BootCryptoInfo; +Partition EncryptedVirtualPartition; + +Partition ActivePartition; +Partition PartitionFollowingActive; +bool ExtraBootPartitionPresent = false; +uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage +uint64 HiddenVolumeStartSector; + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + +void ReadBootSectorUserConfiguration () +{ + byte userConfig; + + AcquireSectorBuffer(); + + if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess) + goto ret; + + userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; + +#ifdef TC_WINDOWS_BOOT_AES + EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION)); +#endif + + PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC); + + memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); + CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0; + + if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE) + { + if (CustomUserMessage[0]) + { + InitVideoMode(); + Print (CustomUserMessage); + } + + DisableScreenOutput(); + } + + if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM) + { + PimValueOrHiddenVolumeStartUnitNo.LowPart = 0; + memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE); + } + else + PimValueOrHiddenVolumeStartUnitNo.LowPart = -1; + + OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET); + +ret: + ReleaseSectorBuffer(); +} + + +BiosResult UpdateBootSectorConfiguration (byte drive) +{ + AcquireSectorBuffer(); + + BiosResult result = ReadWriteMBR (false, drive); + if (result != BiosResultSuccess) + goto ret; + + SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags; + result = ReadWriteMBR (true, drive); + +ret: + ReleaseSectorBuffer(); + return result; +} + +#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE diff --git a/src/Boot/Windows/BootConfig.h b/src/Boot/Windows/BootConfig.h index 0c5eee74..0a06a987 100644 --- a/src/Boot/Windows/BootConfig.h +++ b/src/Boot/Windows/BootConfig.h @@ -1,46 +1,46 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootConfig -#define TC_HEADER_Boot_BootConfig - -#include "Crypto.h" -#include "Platform.h" -#include "BootDiskIo.h" - -extern byte BootSectorFlags; - -extern byte BootLoaderDrive; -extern byte BootDrive; -extern bool BootDriveGeometryValid; -extern DriveGeometry BootDriveGeometry; -extern bool PreventNormalSystemBoot; -extern bool PreventBootMenu; -extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; -extern uint32 OuterVolumeBackupHeaderCrc; - -extern bool BootStarted; - -extern CRYPTO_INFO *BootCryptoInfo; -extern Partition EncryptedVirtualPartition; - -extern Partition ActivePartition; -extern Partition PartitionFollowingActive; -extern bool ExtraBootPartitionPresent; -extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage -extern uint64 HiddenVolumeStartSector; - - -void ReadBootSectorUserConfiguration (); -BiosResult UpdateBootSectorConfiguration (byte drive); - -#endif // TC_HEADER_Boot_BootConfig +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootConfig +#define TC_HEADER_Boot_BootConfig + +#include "Crypto.h" +#include "Platform.h" +#include "BootDiskIo.h" + +extern byte BootSectorFlags; + +extern byte BootLoaderDrive; +extern byte BootDrive; +extern bool BootDriveGeometryValid; +extern DriveGeometry BootDriveGeometry; +extern bool PreventNormalSystemBoot; +extern bool PreventBootMenu; +extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; +extern uint32 OuterVolumeBackupHeaderCrc; + +extern bool BootStarted; + +extern CRYPTO_INFO *BootCryptoInfo; +extern Partition EncryptedVirtualPartition; + +extern Partition ActivePartition; +extern Partition PartitionFollowingActive; +extern bool ExtraBootPartitionPresent; +extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage +extern uint64 HiddenVolumeStartSector; + + +void ReadBootSectorUserConfiguration (); +BiosResult UpdateBootSectorConfiguration (byte drive); + +#endif // TC_HEADER_Boot_BootConfig diff --git a/src/Boot/Windows/BootConsoleIo.cpp b/src/Boot/Windows/BootConsoleIo.cpp index 31b66673..8b5a1905 100644 --- a/src/Boot/Windows/BootConsoleIo.cpp +++ b/src/Boot/Windows/BootConsoleIo.cpp @@ -1,339 +1,339 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Platform.h" -#include "Bios.h" -#include "BootConsoleIo.h" -#include "BootDebug.h" -#include "BootStrings.h" - - -static int ScreenOutputDisabled = 0; - -void DisableScreenOutput () -{ - ++ScreenOutputDisabled; -} - - -void EnableScreenOutput () -{ - --ScreenOutputDisabled; -} - - -void PrintChar (char c) -{ -#ifdef TC_BOOT_TRACING_ENABLED - WriteDebugPort (c); -#endif - - if (ScreenOutputDisabled) - return; - - __asm - { - mov bx, 7 - mov al, c - mov ah, 0xe - int 0x10 - } -} - - -void PrintCharAtCursor (char c) -{ - if (ScreenOutputDisabled) - return; - - __asm - { - mov bx, 7 - mov al, c - mov cx, 1 - mov ah, 0xa - int 0x10 - } -} - - -void Print (const char *str) -{ - char c; - while (c = *str++) - PrintChar (c); -} - - -void Print (uint32 number) -{ - char str[12]; - int pos = 0; - while (number >= 10) - { - str[pos++] = (char) (number % 10) + '0'; - number /= 10; - } - str[pos] = (char) (number % 10) + '0'; - - while (pos >= 0) - PrintChar (str[pos--]); -} - - -void Print (const uint64 &number) -{ - if (number.HighPart == 0) - Print (number.LowPart); - else - PrintHex (number); -} - - -void PrintHex (byte b) -{ - PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4)); - PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF)); -} - - -void PrintHex (uint16 data) -{ - PrintHex (byte (data >> 8)); - PrintHex (byte (data)); -} - - -void PrintHex (uint32 data) -{ - PrintHex (uint16 (data >> 16)); - PrintHex (uint16 (data)); -} - - -void PrintHex (const uint64 &data) -{ - PrintHex (data.HighPart); - PrintHex (data.LowPart); -} - -void PrintRepeatedChar (char c, int n) -{ - while (n-- > 0) - PrintChar (c); -} - - -void PrintEndl () -{ - Print ("\r\n"); -} - - -void PrintEndl (int cnt) -{ - while (cnt-- > 0) - PrintEndl (); -} - - -void Beep () -{ - PrintChar (7); -} - - -void InitVideoMode () -{ - if (ScreenOutputDisabled) - return; - - __asm - { - // Text mode 80x25 - mov ax, 3 - int 0x10 - - // Page 0 - mov ax, 0x500 - int 0x10 - } -} - - -void ClearScreen () -{ - if (ScreenOutputDisabled) - return; - - __asm - { - // White text on black - mov bh, 7 - xor cx, cx - mov dx, 0x184f - mov ax, 0x600 - int 0x10 - - // Cursor at 0,0 - xor bh, bh - xor dx, dx - mov ah, 2 - int 0x10 - } -} - - -void PrintBackspace () -{ - PrintChar (TC_BIOS_CHAR_BACKSPACE); - PrintCharAtCursor (' '); -} - - -void PrintError (const char *message) -{ - Print (TC_BOOT_STR_ERROR); - Print (message); - PrintEndl(); - Beep(); -} - - -void PrintErrorNoEndl (const char *message) -{ - Print (TC_BOOT_STR_ERROR); - Print (message); - Beep(); -} - - -byte GetShiftFlags () -{ - byte flags; - __asm - { - mov ah, 2 - int 0x16 - mov flags, al - } - - return flags; -} - - -byte GetKeyboardChar () -{ - return GetKeyboardChar (nullptr); -} - - -byte GetKeyboardChar (byte *scanCode) -{ - // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer) - while (!IsKeyboardCharAvailable()); - - byte asciiCode; - byte scan; - __asm - { - mov ah, 0 - int 0x16 - mov asciiCode, al - mov scan, ah - } - - if (scanCode) - *scanCode = scan; - - return asciiCode; -} - - -bool IsKeyboardCharAvailable () -{ - bool available = false; - __asm - { - mov ah, 1 - int 0x16 - jz not_avail - mov available, true - not_avail: - } - - return available; -} - - -bool EscKeyPressed () -{ - if (IsKeyboardCharAvailable ()) - { - byte keyScanCode; - GetKeyboardChar (&keyScanCode); - return keyScanCode == TC_BIOS_KEY_ESC; - } - - return false; -} - - -void ClearBiosKeystrokeBuffer () -{ - __asm - { - push es - xor ax, ax - mov es, ax - mov di, 0x41e - mov cx, 32 - cld - rep stosb - pop es - } -} - - -bool IsPrintable (char c) -{ - return c >= ' ' && c <= '~'; -} - -bool IsDigit (char c) -{ - return c >= '0' && c <= '9'; -} - - -int GetString (char *buffer, size_t bufferSize) -{ - byte c; - byte scanCode; - size_t pos = 0; - - while (pos < bufferSize) - { - c = GetKeyboardChar (&scanCode); - - if (scanCode == TC_BIOS_KEY_ENTER) - break; - - if (scanCode == TC_BIOS_KEY_ESC) - return 0; - - buffer[pos++] = c; - PrintChar (IsPrintable (c) ? c : ' '); - } - - return pos; -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Platform.h" +#include "Bios.h" +#include "BootConsoleIo.h" +#include "BootDebug.h" +#include "BootStrings.h" + + +static int ScreenOutputDisabled = 0; + +void DisableScreenOutput () +{ + ++ScreenOutputDisabled; +} + + +void EnableScreenOutput () +{ + --ScreenOutputDisabled; +} + + +void PrintChar (char c) +{ +#ifdef TC_BOOT_TRACING_ENABLED + WriteDebugPort (c); +#endif + + if (ScreenOutputDisabled) + return; + + __asm + { + mov bx, 7 + mov al, c + mov ah, 0xe + int 0x10 + } +} + + +void PrintCharAtCursor (char c) +{ + if (ScreenOutputDisabled) + return; + + __asm + { + mov bx, 7 + mov al, c + mov cx, 1 + mov ah, 0xa + int 0x10 + } +} + + +void Print (const char *str) +{ + char c; + while (c = *str++) + PrintChar (c); +} + + +void Print (uint32 number) +{ + char str[12]; + int pos = 0; + while (number >= 10) + { + str[pos++] = (char) (number % 10) + '0'; + number /= 10; + } + str[pos] = (char) (number % 10) + '0'; + + while (pos >= 0) + PrintChar (str[pos--]); +} + + +void Print (const uint64 &number) +{ + if (number.HighPart == 0) + Print (number.LowPart); + else + PrintHex (number); +} + + +void PrintHex (byte b) +{ + PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4)); + PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF)); +} + + +void PrintHex (uint16 data) +{ + PrintHex (byte (data >> 8)); + PrintHex (byte (data)); +} + + +void PrintHex (uint32 data) +{ + PrintHex (uint16 (data >> 16)); + PrintHex (uint16 (data)); +} + + +void PrintHex (const uint64 &data) +{ + PrintHex (data.HighPart); + PrintHex (data.LowPart); +} + +void PrintRepeatedChar (char c, int n) +{ + while (n-- > 0) + PrintChar (c); +} + + +void PrintEndl () +{ + Print ("\r\n"); +} + + +void PrintEndl (int cnt) +{ + while (cnt-- > 0) + PrintEndl (); +} + + +void Beep () +{ + PrintChar (7); +} + + +void InitVideoMode () +{ + if (ScreenOutputDisabled) + return; + + __asm + { + // Text mode 80x25 + mov ax, 3 + int 0x10 + + // Page 0 + mov ax, 0x500 + int 0x10 + } +} + + +void ClearScreen () +{ + if (ScreenOutputDisabled) + return; + + __asm + { + // White text on black + mov bh, 7 + xor cx, cx + mov dx, 0x184f + mov ax, 0x600 + int 0x10 + + // Cursor at 0,0 + xor bh, bh + xor dx, dx + mov ah, 2 + int 0x10 + } +} + + +void PrintBackspace () +{ + PrintChar (TC_BIOS_CHAR_BACKSPACE); + PrintCharAtCursor (' '); +} + + +void PrintError (const char *message) +{ + Print (TC_BOOT_STR_ERROR); + Print (message); + PrintEndl(); + Beep(); +} + + +void PrintErrorNoEndl (const char *message) +{ + Print (TC_BOOT_STR_ERROR); + Print (message); + Beep(); +} + + +byte GetShiftFlags () +{ + byte flags; + __asm + { + mov ah, 2 + int 0x16 + mov flags, al + } + + return flags; +} + + +byte GetKeyboardChar () +{ + return GetKeyboardChar (nullptr); +} + + +byte GetKeyboardChar (byte *scanCode) +{ + // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer) + while (!IsKeyboardCharAvailable()); + + byte asciiCode; + byte scan; + __asm + { + mov ah, 0 + int 0x16 + mov asciiCode, al + mov scan, ah + } + + if (scanCode) + *scanCode = scan; + + return asciiCode; +} + + +bool IsKeyboardCharAvailable () +{ + bool available = false; + __asm + { + mov ah, 1 + int 0x16 + jz not_avail + mov available, true + not_avail: + } + + return available; +} + + +bool EscKeyPressed () +{ + if (IsKeyboardCharAvailable ()) + { + byte keyScanCode; + GetKeyboardChar (&keyScanCode); + return keyScanCode == TC_BIOS_KEY_ESC; + } + + return false; +} + + +void ClearBiosKeystrokeBuffer () +{ + __asm + { + push es + xor ax, ax + mov es, ax + mov di, 0x41e + mov cx, 32 + cld + rep stosb + pop es + } +} + + +bool IsPrintable (char c) +{ + return c >= ' ' && c <= '~'; +} + +bool IsDigit (char c) +{ + return c >= '0' && c <= '9'; +} + + +int GetString (char *buffer, size_t bufferSize) +{ + byte c; + byte scanCode; + size_t pos = 0; + + while (pos < bufferSize) + { + c = GetKeyboardChar (&scanCode); + + if (scanCode == TC_BIOS_KEY_ENTER) + break; + + if (scanCode == TC_BIOS_KEY_ESC) + return 0; + + buffer[pos++] = c; + PrintChar (IsPrintable (c) ? c : ' '); + } + + return pos; +} diff --git a/src/Boot/Windows/BootConsoleIo.h b/src/Boot/Windows/BootConsoleIo.h index 6af75c05..b95036d5 100644 --- a/src/Boot/Windows/BootConsoleIo.h +++ b/src/Boot/Windows/BootConsoleIo.h @@ -1,72 +1,72 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootConsoleIo -#define TC_HEADER_Boot_BootConsoleIo - -#include "Platform.h" - -#define TC_DEBUG_PORT 0 - -#define TC_BIOS_KEY_ESC 1 -#define TC_BIOS_KEY_BACKSPACE 14 -#define TC_BIOS_KEY_ENTER 28 -#define TC_BIOS_KEY_F1 0x3b -#define TC_BIOS_KEY_F2 0x3c -#define TC_BIOS_KEY_F3 0x3d -#define TC_BIOS_KEY_F4 0x3e -#define TC_BIOS_KEY_F5 0x3f -#define TC_BIOS_KEY_F6 0x40 -#define TC_BIOS_KEY_F7 0x41 -#define TC_BIOS_KEY_F8 0x42 -#define TC_BIOS_KEY_F9 0x43 -#define TC_BIOS_KEY_F10 0x44 - -#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6) -#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1) -#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0) - -#define TC_BIOS_CHAR_BACKSPACE 8 - -#define TC_BIOS_MAX_CHARS_PER_LINE 80 - -void Beep (); -void ClearBiosKeystrokeBuffer (); -void ClearScreen (); -void DisableScreenOutput (); -void EnableScreenOutput (); -bool EscKeyPressed (); -byte GetKeyboardChar (); -byte GetKeyboardChar (byte *scanCode); -byte GetShiftFlags (); -int GetString (char *buffer, size_t bufferSize); -void InitVideoMode (); -bool IsKeyboardCharAvailable (); -bool IsPrintable (char c); -bool IsDigit (char c); -void Print (const char *str); -void Print (uint32 number); -void Print (const uint64 &number); -void PrintBackspace (); -void PrintChar (char c); -void PrintCharAtCursor (char c); -void PrintEndl (); -void PrintEndl (int cnt); -void PrintRepeatedChar (char c, int n); -void PrintError (const char *message); -void PrintErrorNoEndl (const char *message); -void PrintHex (byte b); -void PrintHex (uint16 data); -void PrintHex (uint32 data); -void PrintHex (const uint64 &data); - -#endif // TC_HEADER_Boot_BootConsoleIo +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootConsoleIo +#define TC_HEADER_Boot_BootConsoleIo + +#include "Platform.h" + +#define TC_DEBUG_PORT 0 + +#define TC_BIOS_KEY_ESC 1 +#define TC_BIOS_KEY_BACKSPACE 14 +#define TC_BIOS_KEY_ENTER 28 +#define TC_BIOS_KEY_F1 0x3b +#define TC_BIOS_KEY_F2 0x3c +#define TC_BIOS_KEY_F3 0x3d +#define TC_BIOS_KEY_F4 0x3e +#define TC_BIOS_KEY_F5 0x3f +#define TC_BIOS_KEY_F6 0x40 +#define TC_BIOS_KEY_F7 0x41 +#define TC_BIOS_KEY_F8 0x42 +#define TC_BIOS_KEY_F9 0x43 +#define TC_BIOS_KEY_F10 0x44 + +#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6) +#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1) +#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0) + +#define TC_BIOS_CHAR_BACKSPACE 8 + +#define TC_BIOS_MAX_CHARS_PER_LINE 80 + +void Beep (); +void ClearBiosKeystrokeBuffer (); +void ClearScreen (); +void DisableScreenOutput (); +void EnableScreenOutput (); +bool EscKeyPressed (); +byte GetKeyboardChar (); +byte GetKeyboardChar (byte *scanCode); +byte GetShiftFlags (); +int GetString (char *buffer, size_t bufferSize); +void InitVideoMode (); +bool IsKeyboardCharAvailable (); +bool IsPrintable (char c); +bool IsDigit (char c); +void Print (const char *str); +void Print (uint32 number); +void Print (const uint64 &number); +void PrintBackspace (); +void PrintChar (char c); +void PrintCharAtCursor (char c); +void PrintEndl (); +void PrintEndl (int cnt); +void PrintRepeatedChar (char c, int n); +void PrintError (const char *message); +void PrintErrorNoEndl (const char *message); +void PrintHex (byte b); +void PrintHex (uint16 data); +void PrintHex (uint32 data); +void PrintHex (const uint64 &data); + +#endif // TC_HEADER_Boot_BootConsoleIo diff --git a/src/Boot/Windows/BootCrt.asm b/src/Boot/Windows/BootCrt.asm index e309fcb0..fd2c2ef0 100644 --- a/src/Boot/Windows/BootCrt.asm +++ b/src/Boot/Windows/BootCrt.asm @@ -1,27 +1,27 @@ -; -; Derived from source code of TrueCrypt 7.1a, which is -; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed -; by the TrueCrypt License 3.0. -; -; Modifications and additions to the original source code (contained in this file) -; and all other portions of this file are Copyright (c) 2013-2016 IDRIX -; and are governed by the Apache License 2.0 the full text of which is -; contained in the file License.txt included in VeraCrypt binary and source -; code distribution packages. -; - -.MODEL tiny, C -.386 - -INCLUDE BootDefs.i - -EXTERNDEF main:NEAR - -_TEXT SEGMENT -ORG TC_COM_EXECUTABLE_OFFSET - -start: - jmp main - -_TEXT ENDS -END start +; +; Derived from source code of TrueCrypt 7.1a, which is +; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed +; by the TrueCrypt License 3.0. +; +; Modifications and additions to the original source code (contained in this file) +; and all other portions of this file are Copyright (c) 2013-2016 IDRIX +; and are governed by the Apache License 2.0 the full text of which is +; contained in the file License.txt included in VeraCrypt binary and source +; code distribution packages. +; + +.MODEL tiny, C +.386 + +INCLUDE BootDefs.i + +EXTERNDEF main:NEAR + +_TEXT SEGMENT +ORG TC_COM_EXECUTABLE_OFFSET + +start: + jmp main + +_TEXT ENDS +END start diff --git a/src/Boot/Windows/BootDebug.cpp b/src/Boot/Windows/BootDebug.cpp index 0f33ed5a..2c796437 100644 --- a/src/Boot/Windows/BootDebug.cpp +++ b/src/Boot/Windows/BootDebug.cpp @@ -1,181 +1,181 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Platform.h" -#include "Bios.h" -#include "BootConsoleIo.h" -#include "BootDefs.h" -#include "BootDiskIo.h" -#include "BootDebug.h" - - -#ifdef TC_BOOT_TRACING_ENABLED - -void InitDebugPort () -{ - __asm - { - mov dx, TC_DEBUG_PORT - mov ah, 1 - int 0x17 - mov dx, TC_DEBUG_PORT - mov ah, 0xe2 - int 0x17 - } -} - - -void WriteDebugPort (byte dataByte) -{ - __asm - { - mov al, dataByte - mov dx, TC_DEBUG_PORT - mov ah, 0 - int 0x17 - } -} - -#endif // TC_BOOT_TRACING_ENABLED - - -#ifdef TC_BOOT_DEBUG_ENABLED - -extern "C" void PrintDebug (uint32 debugVal) -{ - Print (debugVal); - PrintEndl(); -} - - -void PrintVal (const char *message, const uint32 value, bool newLine, bool hex) -{ - Print (message); - Print (": "); - - if (hex) - PrintHex (value); - else - Print (value); - - if (newLine) - PrintEndl(); -} - - -void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex) -{ - Print (message); - Print (": "); - PrintHex (value); - if (newLine) - PrintEndl(); -} - - -void PrintHexDump (byte *mem, size_t size, uint16 *memSegment) -{ - const size_t width = 16; - for (size_t pos = 0; pos < size; ) - { - for (int pass = 1; pass <= 2; ++pass) - { - size_t i; - for (i = 0; i < width && pos < size; ++i) - { - byte dataByte; - if (memSegment) - { - __asm - { - push es - mov si, ss:memSegment - mov es, ss:[si] - mov si, ss:mem - add si, pos - mov al, es:[si] - mov dataByte, al - pop es - } - pos++; - } - else - dataByte = mem[pos++]; - - if (pass == 1) - { - PrintHex (dataByte); - PrintChar (' '); - } - else - PrintChar (IsPrintable (dataByte) ? dataByte : '.'); - } - - if (pass == 1) - { - pos -= i; - PrintChar (' '); - } - } - - PrintEndl (); - } -} - - -void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size) -{ - PrintHexDump ((byte *) memOffset, size, &memSegment); -} - -#endif // TC_BOOT_DEBUG_ENABLED - - -#ifdef TC_BOOT_STACK_CHECKING_ENABLED - -extern "C" char end[]; - -static void PrintStackInfo () -{ - uint16 spReg; - __asm mov spReg, sp - - Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg); - Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end); -} - - -void CheckStack () -{ - uint16 spReg; - __asm mov spReg, sp - - if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end) - { - __asm cli - __asm mov sp, TC_BOOT_LOADER_STACK_TOP - - PrintError ("Stack overflow"); - TC_THROW_FATAL_EXCEPTION; - } -} - - -void InitStackChecker () -{ - *(uint32 *) end = 0x12345678UL; - - PrintStackInfo(); - PrintEndl(); -} - -#endif // TC_BOOT_STACK_CHECKING_ENABLED +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Platform.h" +#include "Bios.h" +#include "BootConsoleIo.h" +#include "BootDefs.h" +#include "BootDiskIo.h" +#include "BootDebug.h" + + +#ifdef TC_BOOT_TRACING_ENABLED + +void InitDebugPort () +{ + __asm + { + mov dx, TC_DEBUG_PORT + mov ah, 1 + int 0x17 + mov dx, TC_DEBUG_PORT + mov ah, 0xe2 + int 0x17 + } +} + + +void WriteDebugPort (byte dataByte) +{ + __asm + { + mov al, dataByte + mov dx, TC_DEBUG_PORT + mov ah, 0 + int 0x17 + } +} + +#endif // TC_BOOT_TRACING_ENABLED + + +#ifdef TC_BOOT_DEBUG_ENABLED + +extern "C" void PrintDebug (uint32 debugVal) +{ + Print (debugVal); + PrintEndl(); +} + + +void PrintVal (const char *message, const uint32 value, bool newLine, bool hex) +{ + Print (message); + Print (": "); + + if (hex) + PrintHex (value); + else + Print (value); + + if (newLine) + PrintEndl(); +} + + +void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex) +{ + Print (message); + Print (": "); + PrintHex (value); + if (newLine) + PrintEndl(); +} + + +void PrintHexDump (byte *mem, size_t size, uint16 *memSegment) +{ + const size_t width = 16; + for (size_t pos = 0; pos < size; ) + { + for (int pass = 1; pass <= 2; ++pass) + { + size_t i; + for (i = 0; i < width && pos < size; ++i) + { + byte dataByte; + if (memSegment) + { + __asm + { + push es + mov si, ss:memSegment + mov es, ss:[si] + mov si, ss:mem + add si, pos + mov al, es:[si] + mov dataByte, al + pop es + } + pos++; + } + else + dataByte = mem[pos++]; + + if (pass == 1) + { + PrintHex (dataByte); + PrintChar (' '); + } + else + PrintChar (IsPrintable (dataByte) ? dataByte : '.'); + } + + if (pass == 1) + { + pos -= i; + PrintChar (' '); + } + } + + PrintEndl (); + } +} + + +void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size) +{ + PrintHexDump ((byte *) memOffset, size, &memSegment); +} + +#endif // TC_BOOT_DEBUG_ENABLED + + +#ifdef TC_BOOT_STACK_CHECKING_ENABLED + +extern "C" char end[]; + +static void PrintStackInfo () +{ + uint16 spReg; + __asm mov spReg, sp + + Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg); + Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end); +} + + +void CheckStack () +{ + uint16 spReg; + __asm mov spReg, sp + + if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end) + { + __asm cli + __asm mov sp, TC_BOOT_LOADER_STACK_TOP + + PrintError ("Stack overflow"); + TC_THROW_FATAL_EXCEPTION; + } +} + + +void InitStackChecker () +{ + *(uint32 *) end = 0x12345678UL; + + PrintStackInfo(); + PrintEndl(); +} + +#endif // TC_BOOT_STACK_CHECKING_ENABLED diff --git a/src/Boot/Windows/BootDebug.h b/src/Boot/Windows/BootDebug.h index 138dcf62..a10c7fec 100644 --- a/src/Boot/Windows/BootDebug.h +++ b/src/Boot/Windows/BootDebug.h @@ -1,60 +1,60 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootDebug -#define TC_HEADER_Boot_BootDebug - -#include "Platform.h" -#include "BootConsoleIo.h" - -#if 0 -# define TC_BOOT_DEBUG_ENABLED -#endif - -#if 0 || defined (TC_BOOT_DEBUG_ENABLED) -# define TC_BOOT_STACK_CHECKING_ENABLED - extern "C" void CheckStack (); -#else -# define CheckStack() -#endif - -#if 0 -# define TC_BOOT_TRACING_ENABLED -# if 1 -# define TC_TRACE_INT13 -# endif -# if 0 -# define TC_TRACE_INT15 -# endif -#endif - -#ifdef TC_BOOT_DEBUG_ENABLED -# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false) -# define trace_val(VAL) PrintVal (#VAL, VAL); -# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false) -# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false) -#else -# define trace_point -# define trace_val(VAL) -# define trace_hex(VAL) -# define assert(COND) -#endif - -void InitDebugPort (); -void InitStackChecker (); -void WriteDebugPort (byte dataByte); -void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr); -void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size); -void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false); -void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false); - -#endif // TC_HEADER_Boot_BootDebug +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootDebug +#define TC_HEADER_Boot_BootDebug + +#include "Platform.h" +#include "BootConsoleIo.h" + +#if 0 +# define TC_BOOT_DEBUG_ENABLED +#endif + +#if 0 || defined (TC_BOOT_DEBUG_ENABLED) +# define TC_BOOT_STACK_CHECKING_ENABLED + extern "C" void CheckStack (); +#else +# define CheckStack() +#endif + +#if 0 +# define TC_BOOT_TRACING_ENABLED +# if 1 +# define TC_TRACE_INT13 +# endif +# if 0 +# define TC_TRACE_INT15 +# endif +#endif + +#ifdef TC_BOOT_DEBUG_ENABLED +# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false) +# define trace_val(VAL) PrintVal (#VAL, VAL); +# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false) +# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false) +#else +# define trace_point +# define trace_val(VAL) +# define trace_hex(VAL) +# define assert(COND) +#endif + +void InitDebugPort (); +void InitStackChecker (); +void WriteDebugPort (byte dataByte); +void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr); +void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size); +void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false); +void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false); + +#endif // TC_HEADER_Boot_BootDebug diff --git a/src/Boot/Windows/BootDefs.h b/src/Boot/Windows/BootDefs.h index 69c57dbc..2e69d5a3 100644 --- a/src/Boot/Windows/BootDefs.h +++ b/src/Boot/Windows/BootDefs.h @@ -1,199 +1,199 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootDefs -#define TC_HEADER_Boot_BootDefs - -// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map. -#define TC__BOOT_MEMORY_REQUIRED 43 - -#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE -# undef TC__BOOT_MEMORY_REQUIRED - -# ifdef TC_WINDOWS_BOOT_AES -# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE -# define TC__BOOT_MEMORY_REQUIRED 31 -# else -# define TC__BOOT_MEMORY_REQUIRED 29 -# endif -# elif defined (TC_WINDOWS_BOOT_SERPENT) -# define TC__BOOT_MEMORY_REQUIRED 33 -# elif defined (TC_WINDOWS_BOOT_TWOFISH) -# define TC__BOOT_MEMORY_REQUIRED 41 -# endif - -#if 0 -# undef TC__BOOT_MEMORY_REQUIRED -# define TC__BOOT_MEMORY_REQUIRED 60 -#endif - -#endif - -// Modifying this value can introduce incompatibility with previous versions -#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero - -#if TC__BOOT_MEMORY_REQUIRED <= 32 -# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16) -#else -# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16) -#endif - -#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100) - -#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000) -#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000) -#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000) - -#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4) - -#define TC__LB_SIZE 512 -#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63 - -#define TC__BOOT_SECTOR_VERSION_OFFSET 430 -#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432 -#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434 -#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438 -#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader - -#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24 -#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH) - -#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4 -#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE) - -#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2 -#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE) - -#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2 -#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4 -#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768 -#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072) - -#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT) -#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2) -#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE) - -#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30 - -#define TC__GZIP_HEADER_SIZE 10 - -#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes - -// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE -#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02) -#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04) -#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10) -#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20) -#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80)) - -// Modifying the following values can introduce incompatibility with previous versions -#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01) -#define TC__BOOT_USER_CFG_FLAG_DISABLE_ESC TC_HEX (02) -#define TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC_HEX (04) -#define TC__BOOT_USER_CFG_FLAG_DISABLE_PIM TC_HEX (08) - -// The following items are treated as a 2-bit value (apply TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE to obtain the value) -#define TC__HIDDEN_OS_CREATION_PHASE_NONE 0 -#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume -#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now. -#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now. - - -#ifdef TC_ASM_PREPROCESS - -#define TC_HEX(N) 0##N##h -#define TC_UNSIGNED(N) N - -TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED -TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT -TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW -TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET -TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT -TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT -TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT -TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP -TC_LB_SIZE = TC__LB_SIZE -TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT -TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET -TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET -TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET -TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET -TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR -TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT -TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE -TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET -TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR -TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT -TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE -TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT -TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE -TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE -TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE -TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER -TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER -TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE -TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE -TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE -TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING -TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING -TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED - -#else // TC_ASM_PREPROCESS - -#define TC_HEX(N) 0x##N -#define TC_UNSIGNED(N) N##U - -#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED -#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT -#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET -#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT -#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT -#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT -#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP) -#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT -#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET -#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE -#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET -#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE -#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET -#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH -#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET -#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET -#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET -#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR -#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT -#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET -#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET -#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR -#define TC_LB_SIZE TC__LB_SIZE -#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT -#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE -#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT -#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE -#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE -#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE -#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER -#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER -#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION -#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE -#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE -#define TC_BOOT_USER_CFG_FLAG_DISABLE_ESC TC__BOOT_USER_CFG_FLAG_DISABLE_ESC -#define TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION -#define TC_BOOT_USER_CFG_FLAG_DISABLE_PIM TC__BOOT_USER_CFG_FLAG_DISABLE_PIM -#define TC_HIDDEN_OS_CREATION_PHASE_NONE TC__HIDDEN_OS_CREATION_PHASE_NONE -#define TC_HIDDEN_OS_CREATION_PHASE_CLONING TC__HIDDEN_OS_CREATION_PHASE_CLONING -#define TC_HIDDEN_OS_CREATION_PHASE_WIPING TC__HIDDEN_OS_CREATION_PHASE_WIPING -#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED - -#endif // TC_ASM_PREPROCESS - -#endif // TC_HEADER_Boot_BootDefs +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootDefs +#define TC_HEADER_Boot_BootDefs + +// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map. +#define TC__BOOT_MEMORY_REQUIRED 43 + +#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE +# undef TC__BOOT_MEMORY_REQUIRED + +# ifdef TC_WINDOWS_BOOT_AES +# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE +# define TC__BOOT_MEMORY_REQUIRED 31 +# else +# define TC__BOOT_MEMORY_REQUIRED 29 +# endif +# elif defined (TC_WINDOWS_BOOT_SERPENT) +# define TC__BOOT_MEMORY_REQUIRED 33 +# elif defined (TC_WINDOWS_BOOT_TWOFISH) +# define TC__BOOT_MEMORY_REQUIRED 41 +# endif + +#if 0 +# undef TC__BOOT_MEMORY_REQUIRED +# define TC__BOOT_MEMORY_REQUIRED 60 +#endif + +#endif + +// Modifying this value can introduce incompatibility with previous versions +#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero + +#if TC__BOOT_MEMORY_REQUIRED <= 32 +# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16) +#else +# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16) +#endif + +#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100) + +#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000) +#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000) +#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000) + +#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4) + +#define TC__LB_SIZE 512 +#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63 + +#define TC__BOOT_SECTOR_VERSION_OFFSET 430 +#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432 +#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434 +#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438 +#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader + +#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24 +#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH) + +#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4 +#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE) + +#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2 +#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE) + +#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2 +#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4 +#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768 +#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072) + +#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT) +#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2) +#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE) + +#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30 + +#define TC__GZIP_HEADER_SIZE 10 + +#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes + +// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE +#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02) +#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04) +#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10) +#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20) +#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80)) + +// Modifying the following values can introduce incompatibility with previous versions +#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01) +#define TC__BOOT_USER_CFG_FLAG_DISABLE_ESC TC_HEX (02) +#define TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC_HEX (04) +#define TC__BOOT_USER_CFG_FLAG_DISABLE_PIM TC_HEX (08) + +// The following items are treated as a 2-bit value (apply TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE to obtain the value) +#define TC__HIDDEN_OS_CREATION_PHASE_NONE 0 +#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume +#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now. +#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now. + + +#ifdef TC_ASM_PREPROCESS + +#define TC_HEX(N) 0##N##h +#define TC_UNSIGNED(N) N + +TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED +TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT +TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW +TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET +TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT +TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT +TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT +TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP +TC_LB_SIZE = TC__LB_SIZE +TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT +TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET +TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET +TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET +TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET +TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR +TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT +TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE +TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET +TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR +TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT +TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE +TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT +TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE +TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE +TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE +TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER +TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER +TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE +TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE +TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE +TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING +TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING +TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED + +#else // TC_ASM_PREPROCESS + +#define TC_HEX(N) 0x##N +#define TC_UNSIGNED(N) N##U + +#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED +#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT +#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET +#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT +#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT +#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT +#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP) +#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT +#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET +#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE +#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET +#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE +#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET +#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH +#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET +#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET +#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET +#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR +#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT +#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET +#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET +#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR +#define TC_LB_SIZE TC__LB_SIZE +#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT +#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE +#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT +#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE +#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE +#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE +#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER +#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER +#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION +#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE +#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE +#define TC_BOOT_USER_CFG_FLAG_DISABLE_ESC TC__BOOT_USER_CFG_FLAG_DISABLE_ESC +#define TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION +#define TC_BOOT_USER_CFG_FLAG_DISABLE_PIM TC__BOOT_USER_CFG_FLAG_DISABLE_PIM +#define TC_HIDDEN_OS_CREATION_PHASE_NONE TC__HIDDEN_OS_CREATION_PHASE_NONE +#define TC_HIDDEN_OS_CREATION_PHASE_CLONING TC__HIDDEN_OS_CREATION_PHASE_CLONING +#define TC_HIDDEN_OS_CREATION_PHASE_WIPING TC__HIDDEN_OS_CREATION_PHASE_WIPING +#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED + +#endif // TC_ASM_PREPROCESS + +#endif // TC_HEADER_Boot_BootDefs diff --git a/src/Boot/Windows/BootDiskIo.cpp b/src/Boot/Windows/BootDiskIo.cpp index 31917a64..bf3fe9fc 100644 --- a/src/Boot/Windows/BootDiskIo.cpp +++ b/src/Boot/Windows/BootDiskIo.cpp @@ -1,491 +1,491 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Bios.h" -#include "BootConsoleIo.h" -#include "BootConfig.h" -#include "BootDebug.h" -#include "BootDefs.h" -#include "BootDiskIo.h" -#include "BootStrings.h" - - -byte SectorBuffer[TC_LB_SIZE]; - -#ifdef TC_BOOT_DEBUG_ENABLED -static bool SectorBufferInUse = false; - -void AcquireSectorBuffer () -{ - if (SectorBufferInUse) - TC_THROW_FATAL_EXCEPTION; - - SectorBufferInUse = true; -} - - -void ReleaseSectorBuffer () -{ - SectorBufferInUse = false; -} - -#endif - - -bool IsLbaSupported (byte drive) -{ - static byte CachedDrive = TC_INVALID_BIOS_DRIVE; - static bool CachedStatus; - uint16 result = 0; - - if (CachedDrive == drive) - goto ret; - - __asm - { - mov bx, 0x55aa - mov dl, drive - mov ah, 0x41 - int 0x13 - jc err - mov result, bx - err: - } - - CachedDrive = drive; - CachedStatus = (result == 0xaa55); -ret: - return CachedStatus; -} - - -void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs) -{ - PrintEndl(); - Print (write ? "Write" : "Read"); Print (" error:"); - Print (error); - Print (" Drive:"); - Print (drive ^ 0x80); - - if (sector) - { - Print (" Sector:"); - Print (*sector); - } - - if (chs) - { - Print (" CHS:"); - Print (*chs); - } - - PrintEndl(); - Beep(); -} - - -void Print (const ChsAddress &chs) -{ - Print (chs.Cylinder); - PrintChar ('/'); - Print (chs.Head); - PrintChar ('/'); - Print (chs.Sector); -} - - -void PrintSectorCountInMB (const uint64 §orCount) -{ - Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB "); -} - - -BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) -{ - CheckStack(); - - byte cylinderLow = (byte) chs.Cylinder; - byte sector = chs.Sector; - sector |= byte (chs.Cylinder >> 2) & 0xc0; - byte function = write ? 0x03 : 0x02; - - BiosResult result; - byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES; - - do - { - result = BiosResultSuccess; - - __asm - { - push es - mov ax, bufferSegment - mov es, ax - mov bx, bufferOffset - mov dl, drive - mov ch, cylinderLow - mov si, chs - mov dh, [si].Head - mov cl, sector - mov al, sectorCount - mov ah, function - int 0x13 - jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes - mov result, ah - ok: - pop es - } - - if (result == BiosResultEccCorrected) - result = BiosResultSuccess; - - // Some BIOSes report I/O errors prematurely in some cases - } while (result != BiosResultSuccess && --tryCount != 0); - - if (!silent && result != BiosResultSuccess) - PrintDiskError (result, write, drive, nullptr, &chs); - - return result; -} - - -BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) -{ - uint16 codeSeg; - __asm mov codeSeg, cs - return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent); -} - - -BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) -{ - return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent); -} - - -BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) -{ - return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent); -} - - -static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - CheckStack(); - - if (!IsLbaSupported (drive)) - { - DriveGeometry geometry; - - BiosResult result = GetDriveGeometry (drive, geometry, silent); - if (result != BiosResultSuccess) - return result; - - ChsAddress chs; - LbaToChs (geometry, sector, chs); - return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent); - } - - dapPacket.Size = sizeof (dapPacket); - dapPacket.Reserved = 0; - dapPacket.SectorCount = sectorCount; - dapPacket.Sector = sector; - - byte function = write ? 0x43 : 0x42; - - BiosResult result; - byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES; - - do - { - result = BiosResultSuccess; - - __asm - { - mov bx, 0x55aa - mov dl, drive - mov si, [dapPacket] - mov ah, function - xor al, al - int 0x13 - jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes - mov result, ah - ok: - } - - if (result == BiosResultEccCorrected) - result = BiosResultSuccess; - - // Some BIOSes report I/O errors prematurely in some cases - } while (result != BiosResultSuccess && --tryCount != 0); - - if (!silent && result != BiosResultSuccess) - PrintDiskError (result, write, drive, §or); - - return result; -} - - -static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - BiosLbaPacket dapPacket; - dapPacket.Buffer = (uint32) buffer; - return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent); -} - - -BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - BiosLbaPacket dapPacket; - dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset; - return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent); -} - -BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent); -} - - -BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - BiosResult result; - uint16 codeSeg; - __asm mov codeSeg, cs - - result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent); - - // Alternative segment is used to prevent memory corruption caused by buggy BIOSes - if (!BootStarted) - CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE); - - return result; -} - - -BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) -{ - return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent); -} - - -BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent) -{ - CheckStack(); - - byte maxCylinderLow, maxHead, maxSector; - BiosResult result; - __asm - { - push es - mov dl, drive - mov ah, 0x08 - int 0x13 - - mov result, ah - mov maxCylinderLow, ch - mov maxSector, cl - mov maxHead, dh - pop es - } - - if (result == BiosResultSuccess) - { - geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1; - geometry.Heads = maxHead + 1; - geometry.Sectors = maxSector & ~0xc0; - } - else if (!silent) - { - Print ("Drive "); - Print (drive ^ 0x80); - Print (" not found: "); - PrintErrorNoEndl (""); - Print (result); - PrintEndl(); - } - - return result; -} - - -void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba) -{ - lba.HighPart = 0; - lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1; -} - - -void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs) -{ - chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1); - uint32 ch = lba.LowPart / geometry.Sectors; - chs.Head = (byte) (ch % geometry.Heads); - chs.Cylinder = (uint16) (ch / geometry.Heads); -} - - -void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition) -{ - partition.Active = partEntry.BootIndicator == 0x80; - partition.EndSector.HighPart = 0; - partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1; - partition.SectorCount.HighPart = 0; - partition.SectorCount.LowPart = partEntry.SectorCountLBA; - partition.StartSector.HighPart = 0; - partition.StartSector.LowPart = partEntry.StartLBA; - partition.Type = partEntry.Type; -} - - -BiosResult ReadWriteMBR (bool write, byte drive, bool silent) -{ - uint64 mbrSector; - mbrSector.HighPart = 0; - mbrSector.LowPart = 0; - - if (write) - return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent); - - return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment -} - - -BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent) -{ - Partition *followingPartition; - Partition tmpPartition; - - if (findPartitionFollowingThis) - { - assert (partitionArrayCapacity == 1); - partitionArrayCapacity = 0xff; - followingPartition = partitionArray; - partitionArray = &tmpPartition; - - followingPartition->Drive = TC_INVALID_BIOS_DRIVE; - followingPartition->StartSector.LowPart = 0xFFFFffffUL; - } - - AcquireSectorBuffer(); - BiosResult result = ReadWriteMBR (false, drive, silent); - ReleaseSectorBuffer(); - - partitionCount = 0; - - MBR *mbr = (MBR *) SectorBuffer; - if (result != BiosResultSuccess || mbr->Signature != 0xaa55) - return result; - - PartitionEntryMBR mbrPartitions[4]; - memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions)); - size_t partitionArrayPos = 0, partitionNumber; - - for (partitionNumber = 0; - partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity; - ++partitionNumber) - { - const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber]; - - if (partEntry.SectorCountLBA > 0) - { - Partition &partition = partitionArray[partitionArrayPos]; - PartitionEntryMBRToPartition (partEntry, partition); - - if (activeOnly && !partition.Active) - continue; - - partition.Drive = drive; - partition.Number = partitionArrayPos; - - if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition - { - if (IsLbaSupported (drive)) - { - // Find all extended partitions - uint64 firstExtStartLBA = partition.StartSector; - uint64 extStartLBA = partition.StartSector; - MBR *extMbr = (MBR *) SectorBuffer; - - while (partitionArrayPos < partitionArrayCapacity && - (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess - && extMbr->Signature == 0xaa55) - { - if (extMbr->Partitions[0].SectorCountLBA > 0) - { - Partition &logPart = partitionArray[partitionArrayPos]; - PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart); - logPart.Drive = drive; - - logPart.Number = partitionArrayPos; - logPart.Primary = false; - - logPart.StartSector.LowPart += extStartLBA.LowPart; - logPart.EndSector.LowPart += extStartLBA.LowPart; - - if (findPartitionFollowingThis) - { - if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart - && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart) - { - *followingPartition = logPart; - } - } - else - ++partitionArrayPos; - } - - // Secondary extended - if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf - || extMbr->Partitions[1].SectorCountLBA == 0) - break; - - extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart; - } - } - } - else - { - partition.Primary = true; - - if (findPartitionFollowingThis) - { - if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart - && partition.StartSector.LowPart < followingPartition->StartSector.LowPart) - { - *followingPartition = partition; - } - } - else - ++partitionArrayPos; - } - } - } - - partitionCount = partitionArrayPos; - return result; -} - - -bool GetActivePartition (byte drive) -{ - size_t partCount; - - if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1) - { - ActivePartition.Drive = TC_INVALID_BIOS_DRIVE; - PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); - return false; - } - - return true; -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Bios.h" +#include "BootConsoleIo.h" +#include "BootConfig.h" +#include "BootDebug.h" +#include "BootDefs.h" +#include "BootDiskIo.h" +#include "BootStrings.h" + + +byte SectorBuffer[TC_LB_SIZE]; + +#ifdef TC_BOOT_DEBUG_ENABLED +static bool SectorBufferInUse = false; + +void AcquireSectorBuffer () +{ + if (SectorBufferInUse) + TC_THROW_FATAL_EXCEPTION; + + SectorBufferInUse = true; +} + + +void ReleaseSectorBuffer () +{ + SectorBufferInUse = false; +} + +#endif + + +bool IsLbaSupported (byte drive) +{ + static byte CachedDrive = TC_INVALID_BIOS_DRIVE; + static bool CachedStatus; + uint16 result = 0; + + if (CachedDrive == drive) + goto ret; + + __asm + { + mov bx, 0x55aa + mov dl, drive + mov ah, 0x41 + int 0x13 + jc err + mov result, bx + err: + } + + CachedDrive = drive; + CachedStatus = (result == 0xaa55); +ret: + return CachedStatus; +} + + +void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs) +{ + PrintEndl(); + Print (write ? "Write" : "Read"); Print (" error:"); + Print (error); + Print (" Drive:"); + Print (drive ^ 0x80); + + if (sector) + { + Print (" Sector:"); + Print (*sector); + } + + if (chs) + { + Print (" CHS:"); + Print (*chs); + } + + PrintEndl(); + Beep(); +} + + +void Print (const ChsAddress &chs) +{ + Print (chs.Cylinder); + PrintChar ('/'); + Print (chs.Head); + PrintChar ('/'); + Print (chs.Sector); +} + + +void PrintSectorCountInMB (const uint64 §orCount) +{ + Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB "); +} + + +BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) +{ + CheckStack(); + + byte cylinderLow = (byte) chs.Cylinder; + byte sector = chs.Sector; + sector |= byte (chs.Cylinder >> 2) & 0xc0; + byte function = write ? 0x03 : 0x02; + + BiosResult result; + byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES; + + do + { + result = BiosResultSuccess; + + __asm + { + push es + mov ax, bufferSegment + mov es, ax + mov bx, bufferOffset + mov dl, drive + mov ch, cylinderLow + mov si, chs + mov dh, [si].Head + mov cl, sector + mov al, sectorCount + mov ah, function + int 0x13 + jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes + mov result, ah + ok: + pop es + } + + if (result == BiosResultEccCorrected) + result = BiosResultSuccess; + + // Some BIOSes report I/O errors prematurely in some cases + } while (result != BiosResultSuccess && --tryCount != 0); + + if (!silent && result != BiosResultSuccess) + PrintDiskError (result, write, drive, nullptr, &chs); + + return result; +} + + +BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) +{ + uint16 codeSeg; + __asm mov codeSeg, cs + return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent); +} + + +BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) +{ + return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent); +} + + +BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent) +{ + return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent); +} + + +static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + CheckStack(); + + if (!IsLbaSupported (drive)) + { + DriveGeometry geometry; + + BiosResult result = GetDriveGeometry (drive, geometry, silent); + if (result != BiosResultSuccess) + return result; + + ChsAddress chs; + LbaToChs (geometry, sector, chs); + return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent); + } + + dapPacket.Size = sizeof (dapPacket); + dapPacket.Reserved = 0; + dapPacket.SectorCount = sectorCount; + dapPacket.Sector = sector; + + byte function = write ? 0x43 : 0x42; + + BiosResult result; + byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES; + + do + { + result = BiosResultSuccess; + + __asm + { + mov bx, 0x55aa + mov dl, drive + mov si, [dapPacket] + mov ah, function + xor al, al + int 0x13 + jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes + mov result, ah + ok: + } + + if (result == BiosResultEccCorrected) + result = BiosResultSuccess; + + // Some BIOSes report I/O errors prematurely in some cases + } while (result != BiosResultSuccess && --tryCount != 0); + + if (!silent && result != BiosResultSuccess) + PrintDiskError (result, write, drive, §or); + + return result; +} + + +static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + BiosLbaPacket dapPacket; + dapPacket.Buffer = (uint32) buffer; + return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent); +} + + +BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + BiosLbaPacket dapPacket; + dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset; + return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent); +} + +BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent); +} + + +BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + BiosResult result; + uint16 codeSeg; + __asm mov codeSeg, cs + + result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent); + + // Alternative segment is used to prevent memory corruption caused by buggy BIOSes + if (!BootStarted) + CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE); + + return result; +} + + +BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent) +{ + return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent); +} + + +BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent) +{ + CheckStack(); + + byte maxCylinderLow, maxHead, maxSector; + BiosResult result; + __asm + { + push es + mov dl, drive + mov ah, 0x08 + int 0x13 + + mov result, ah + mov maxCylinderLow, ch + mov maxSector, cl + mov maxHead, dh + pop es + } + + if (result == BiosResultSuccess) + { + geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1; + geometry.Heads = maxHead + 1; + geometry.Sectors = maxSector & ~0xc0; + } + else if (!silent) + { + Print ("Drive "); + Print (drive ^ 0x80); + Print (" not found: "); + PrintErrorNoEndl (""); + Print (result); + PrintEndl(); + } + + return result; +} + + +void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba) +{ + lba.HighPart = 0; + lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1; +} + + +void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs) +{ + chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1); + uint32 ch = lba.LowPart / geometry.Sectors; + chs.Head = (byte) (ch % geometry.Heads); + chs.Cylinder = (uint16) (ch / geometry.Heads); +} + + +void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition) +{ + partition.Active = partEntry.BootIndicator == 0x80; + partition.EndSector.HighPart = 0; + partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1; + partition.SectorCount.HighPart = 0; + partition.SectorCount.LowPart = partEntry.SectorCountLBA; + partition.StartSector.HighPart = 0; + partition.StartSector.LowPart = partEntry.StartLBA; + partition.Type = partEntry.Type; +} + + +BiosResult ReadWriteMBR (bool write, byte drive, bool silent) +{ + uint64 mbrSector; + mbrSector.HighPart = 0; + mbrSector.LowPart = 0; + + if (write) + return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent); + + return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment +} + + +BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent) +{ + Partition *followingPartition; + Partition tmpPartition; + + if (findPartitionFollowingThis) + { + assert (partitionArrayCapacity == 1); + partitionArrayCapacity = 0xff; + followingPartition = partitionArray; + partitionArray = &tmpPartition; + + followingPartition->Drive = TC_INVALID_BIOS_DRIVE; + followingPartition->StartSector.LowPart = 0xFFFFffffUL; + } + + AcquireSectorBuffer(); + BiosResult result = ReadWriteMBR (false, drive, silent); + ReleaseSectorBuffer(); + + partitionCount = 0; + + MBR *mbr = (MBR *) SectorBuffer; + if (result != BiosResultSuccess || mbr->Signature != 0xaa55) + return result; + + PartitionEntryMBR mbrPartitions[4]; + memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions)); + size_t partitionArrayPos = 0, partitionNumber; + + for (partitionNumber = 0; + partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity; + ++partitionNumber) + { + const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber]; + + if (partEntry.SectorCountLBA > 0) + { + Partition &partition = partitionArray[partitionArrayPos]; + PartitionEntryMBRToPartition (partEntry, partition); + + if (activeOnly && !partition.Active) + continue; + + partition.Drive = drive; + partition.Number = partitionArrayPos; + + if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition + { + if (IsLbaSupported (drive)) + { + // Find all extended partitions + uint64 firstExtStartLBA = partition.StartSector; + uint64 extStartLBA = partition.StartSector; + MBR *extMbr = (MBR *) SectorBuffer; + + while (partitionArrayPos < partitionArrayCapacity && + (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess + && extMbr->Signature == 0xaa55) + { + if (extMbr->Partitions[0].SectorCountLBA > 0) + { + Partition &logPart = partitionArray[partitionArrayPos]; + PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart); + logPart.Drive = drive; + + logPart.Number = partitionArrayPos; + logPart.Primary = false; + + logPart.StartSector.LowPart += extStartLBA.LowPart; + logPart.EndSector.LowPart += extStartLBA.LowPart; + + if (findPartitionFollowingThis) + { + if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart + && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart) + { + *followingPartition = logPart; + } + } + else + ++partitionArrayPos; + } + + // Secondary extended + if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf + || extMbr->Partitions[1].SectorCountLBA == 0) + break; + + extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart; + } + } + } + else + { + partition.Primary = true; + + if (findPartitionFollowingThis) + { + if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart + && partition.StartSector.LowPart < followingPartition->StartSector.LowPart) + { + *followingPartition = partition; + } + } + else + ++partitionArrayPos; + } + } + } + + partitionCount = partitionArrayPos; + return result; +} + + +bool GetActivePartition (byte drive) +{ + size_t partCount; + + if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1) + { + ActivePartition.Drive = TC_INVALID_BIOS_DRIVE; + PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); + return false; + } + + return true; +} diff --git a/src/Boot/Windows/BootDiskIo.h b/src/Boot/Windows/BootDiskIo.h index d1c1ccff..b09220a8 100644 --- a/src/Boot/Windows/BootDiskIo.h +++ b/src/Boot/Windows/BootDiskIo.h @@ -1,120 +1,120 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootDiskIo -#define TC_HEADER_Boot_BootDiskIo - -#include "Bios.h" -#include "BootDebug.h" -#include "BootDefs.h" - -#define TC_MAX_BIOS_DISK_IO_RETRIES 5 - -enum -{ - BiosResultEccCorrected = 0x11 -}; - -#pragma pack(1) - -struct PartitionEntryMBR -{ - byte BootIndicator; - - byte StartHead; - byte StartCylSector; - byte StartCylinder; - - byte Type; - - byte EndHead; - byte EndSector; - byte EndCylinder; - - uint32 StartLBA; - uint32 SectorCountLBA; -}; - -struct MBR -{ - byte Code[446]; - PartitionEntryMBR Partitions[4]; - uint16 Signature; -}; - -struct BiosLbaPacket -{ - byte Size; - byte Reserved; - uint16 SectorCount; - uint32 Buffer; - uint64 Sector; -}; - -#pragma pack() - - -struct ChsAddress -{ - uint16 Cylinder; - byte Head; - byte Sector; -}; - -struct Partition -{ - byte Number; - byte Drive; - bool Active; - uint64 EndSector; - bool Primary; - uint64 SectorCount; - uint64 StartSector; - byte Type; -}; - -struct DriveGeometry -{ - uint16 Cylinders; - byte Heads; - byte Sectors; -}; - - -#ifdef TC_BOOT_DEBUG_ENABLED -void AcquireSectorBuffer (); -void ReleaseSectorBuffer (); -#else -# define AcquireSectorBuffer() -# define ReleaseSectorBuffer() -#endif - -void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba); -bool GetActivePartition (byte drive); -BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false); -BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false); -bool IsLbaSupported (byte drive); -void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs); -void Print (const ChsAddress &chs); -void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr); -void PrintSectorCountInMB (const uint64 §orCount); -BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false); -BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); -BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); -BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false); -BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent); -BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); -BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false); - -extern byte SectorBuffer[TC_LB_SIZE]; - -#endif // TC_HEADER_Boot_BootDiskIo +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootDiskIo +#define TC_HEADER_Boot_BootDiskIo + +#include "Bios.h" +#include "BootDebug.h" +#include "BootDefs.h" + +#define TC_MAX_BIOS_DISK_IO_RETRIES 5 + +enum +{ + BiosResultEccCorrected = 0x11 +}; + +#pragma pack(1) + +struct PartitionEntryMBR +{ + byte BootIndicator; + + byte StartHead; + byte StartCylSector; + byte StartCylinder; + + byte Type; + + byte EndHead; + byte EndSector; + byte EndCylinder; + + uint32 StartLBA; + uint32 SectorCountLBA; +}; + +struct MBR +{ + byte Code[446]; + PartitionEntryMBR Partitions[4]; + uint16 Signature; +}; + +struct BiosLbaPacket +{ + byte Size; + byte Reserved; + uint16 SectorCount; + uint32 Buffer; + uint64 Sector; +}; + +#pragma pack() + + +struct ChsAddress +{ + uint16 Cylinder; + byte Head; + byte Sector; +}; + +struct Partition +{ + byte Number; + byte Drive; + bool Active; + uint64 EndSector; + bool Primary; + uint64 SectorCount; + uint64 StartSector; + byte Type; +}; + +struct DriveGeometry +{ + uint16 Cylinders; + byte Heads; + byte Sectors; +}; + + +#ifdef TC_BOOT_DEBUG_ENABLED +void AcquireSectorBuffer (); +void ReleaseSectorBuffer (); +#else +# define AcquireSectorBuffer() +# define ReleaseSectorBuffer() +#endif + +void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba); +bool GetActivePartition (byte drive); +BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false); +BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false); +bool IsLbaSupported (byte drive); +void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs); +void Print (const ChsAddress &chs); +void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr); +void PrintSectorCountInMB (const uint64 §orCount); +BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false); +BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); +BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); +BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false); +BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent); +BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); +BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false); + +extern byte SectorBuffer[TC_LB_SIZE]; + +#endif // TC_HEADER_Boot_BootDiskIo diff --git a/src/Boot/Windows/BootEncryptedIo.cpp b/src/Boot/Windows/BootEncryptedIo.cpp index d130534f..84a4bf14 100644 --- a/src/Boot/Windows/BootEncryptedIo.cpp +++ b/src/Boot/Windows/BootEncryptedIo.cpp @@ -1,132 +1,132 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Crypto.h" -#include "Platform.h" -#include "BootConfig.h" -#include "BootDebug.h" -#include "BootDefs.h" -#include "BootDiskIo.h" -#include "BootEncryptedIo.h" - - -BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount) -{ - BiosResult result; - bool decrypt = true; - - if (BootCryptoInfo->hiddenVolume) - { - if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) - return BiosResultInvalidFunction; - - if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) - { - // Remap the request to the hidden volume - sector -= EncryptedVirtualPartition.StartSector; - sector += HiddenVolumeStartSector; - } - else - decrypt = false; - } - - result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount); - - if (result != BiosResultSuccess || !decrypt) - return result; - - if (BootCryptoInfo->hiddenVolume) - { - // Convert sector number to data unit number of the hidden volume - sector -= HiddenVolumeStartSector; - sector += PimValueOrHiddenVolumeStartUnitNo; - } - - if (drive == EncryptedVirtualPartition.Drive) - { - while (sectorCount-- > 0) - { - if (BootCryptoInfo->hiddenVolume - || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)) - { - AcquireSectorBuffer(); - CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE); - - DecryptDataUnits (SectorBuffer, §or, 1, BootCryptoInfo); - - CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE); - ReleaseSectorBuffer(); - } - - ++sector; - destOffset += TC_LB_SIZE; - } - } - - return result; -} - - -BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount) -{ - BiosResult result = BiosResultSuccess; - AcquireSectorBuffer(); - uint64 dataUnitNo; - uint64 writeOffset; - - dataUnitNo = sector; - writeOffset.HighPart = 0; - writeOffset.LowPart = 0; - - if (BootCryptoInfo->hiddenVolume) - { - if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) - return BiosResultInvalidFunction; - - // Remap the request to the hidden volume - writeOffset = HiddenVolumeStartSector; - writeOffset -= EncryptedVirtualPartition.StartSector; - dataUnitNo -= EncryptedVirtualPartition.StartSector; - dataUnitNo += PimValueOrHiddenVolumeStartUnitNo; - } - - while (sectorCount-- > 0) - { - CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE); - - if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) - { - EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo); - } - - result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1); - - if (result != BiosResultSuccess) - break; - - ++sector; - ++dataUnitNo; - sourceOffset += TC_LB_SIZE; - } - - ReleaseSectorBuffer(); - return result; -} - - -static bool ReadWritePartiallyCoversEncryptedArea (const uint64 §or, uint16 sectorCount) -{ - uint64 readWriteEnd = sector + --sectorCount; - - return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector) - || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector)); -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Crypto.h" +#include "Platform.h" +#include "BootConfig.h" +#include "BootDebug.h" +#include "BootDefs.h" +#include "BootDiskIo.h" +#include "BootEncryptedIo.h" + + +BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount) +{ + BiosResult result; + bool decrypt = true; + + if (BootCryptoInfo->hiddenVolume) + { + if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) + return BiosResultInvalidFunction; + + if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) + { + // Remap the request to the hidden volume + sector -= EncryptedVirtualPartition.StartSector; + sector += HiddenVolumeStartSector; + } + else + decrypt = false; + } + + result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount); + + if (result != BiosResultSuccess || !decrypt) + return result; + + if (BootCryptoInfo->hiddenVolume) + { + // Convert sector number to data unit number of the hidden volume + sector -= HiddenVolumeStartSector; + sector += PimValueOrHiddenVolumeStartUnitNo; + } + + if (drive == EncryptedVirtualPartition.Drive) + { + while (sectorCount-- > 0) + { + if (BootCryptoInfo->hiddenVolume + || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)) + { + AcquireSectorBuffer(); + CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE); + + DecryptDataUnits (SectorBuffer, §or, 1, BootCryptoInfo); + + CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE); + ReleaseSectorBuffer(); + } + + ++sector; + destOffset += TC_LB_SIZE; + } + } + + return result; +} + + +BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount) +{ + BiosResult result = BiosResultSuccess; + AcquireSectorBuffer(); + uint64 dataUnitNo; + uint64 writeOffset; + + dataUnitNo = sector; + writeOffset.HighPart = 0; + writeOffset.LowPart = 0; + + if (BootCryptoInfo->hiddenVolume) + { + if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) + return BiosResultInvalidFunction; + + // Remap the request to the hidden volume + writeOffset = HiddenVolumeStartSector; + writeOffset -= EncryptedVirtualPartition.StartSector; + dataUnitNo -= EncryptedVirtualPartition.StartSector; + dataUnitNo += PimValueOrHiddenVolumeStartUnitNo; + } + + while (sectorCount-- > 0) + { + CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE); + + if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) + { + EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo); + } + + result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1); + + if (result != BiosResultSuccess) + break; + + ++sector; + ++dataUnitNo; + sourceOffset += TC_LB_SIZE; + } + + ReleaseSectorBuffer(); + return result; +} + + +static bool ReadWritePartiallyCoversEncryptedArea (const uint64 §or, uint16 sectorCount) +{ + uint64 readWriteEnd = sector + --sectorCount; + + return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector) + || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector)); +} diff --git a/src/Boot/Windows/BootEncryptedIo.h b/src/Boot/Windows/BootEncryptedIo.h index 6cc375fa..6402e705 100644 --- a/src/Boot/Windows/BootEncryptedIo.h +++ b/src/Boot/Windows/BootEncryptedIo.h @@ -1,22 +1,22 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootEncryptionIo -#define TC_HEADER_Boot_BootEncryptionIo - -#include "Platform.h" - -BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount); -BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount); -static bool ReadWritePartiallyCoversEncryptedArea (const uint64 §or, uint16 sectorCount); - -#endif // TC_HEADER_Boot_BootEncryptionIo +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootEncryptionIo +#define TC_HEADER_Boot_BootEncryptionIo + +#include "Platform.h" + +BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount); +BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount); +static bool ReadWritePartiallyCoversEncryptedArea (const uint64 §or, uint16 sectorCount); + +#endif // TC_HEADER_Boot_BootEncryptionIo diff --git a/src/Boot/Windows/BootMain.cpp b/src/Boot/Windows/BootMain.cpp index 275c5762..24acd23f 100644 --- a/src/Boot/Windows/BootMain.cpp +++ b/src/Boot/Windows/BootMain.cpp @@ -1,1269 +1,1269 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Crc.h" -#include "Crypto.h" -#include "Password.h" -#include "Volumes.h" - -#include "Platform.h" -#include "Bios.h" -#include "BootConfig.h" -#include "BootMain.h" -#include "BootDefs.h" -#include "BootCommon.h" -#include "BootConsoleIo.h" -#include "BootDebug.h" -#include "BootDiskIo.h" -#include "BootEncryptedIo.h" -#include "BootMemory.h" -#include "BootStrings.h" -#include "IntFilter.h" - - -static void InitScreen () -{ - ClearScreen(); - - const char *title = -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - " VeraCrypt Boot Loader " -#else - " VeraCrypt Rescue Disk " -#endif - VERSION_STRING "\r\n"; - - Print (title); - - PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE); - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - if (CustomUserMessage[0]) - { - PrintEndl(); - Print (CustomUserMessage); - } -#endif - - PrintEndl (2); -} - - -static void PrintMainMenu () -{ - if (PreventBootMenu) - return; - - Print (" Keyboard Controls:\r\n"); - Print (" [F5] Hide/Show Password and PIM\r\n"); - Print (" [Esc] "); - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE - ? "Boot Non-Hidden System (Boot Manager)" - : "Skip Authentication (Boot Manager)"); - -#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - Print ("Skip Authentication (Boot Manager)"); - Print ("\r\n [F8] "); Print ("Repair Options"); - -#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - PrintEndl (3); -} - - -static bool IsMenuKey (byte scanCode) -{ -#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - return scanCode == TC_MENU_KEY_REPAIR; -#else - return false; -#endif -} - - -static bool AskYesNo (const char *message) -{ - Print (message); - Print ("? (y/n): "); - while (true) - { - switch (GetKeyboardChar()) - { - case 'y': - case 'Y': - case 'z': - case 'Z': - Print ("y\r\n"); - return true; - - case 'n': - case 'N': - Print ("n\r\n"); - return false; - - default: - Beep(); - } - } -} - - -static int AskSelection (const char *options[], size_t optionCount) -{ - for (int i = 0; i < optionCount; ++i) - { - Print ("["); Print (i + 1); Print ("] "); - Print (options[i]); - PrintEndl(); - } - Print ("[Esc] Cancel\r\n\r\n"); - - Print ("To select, press 1-9: "); - - char str; - - while (true) - { - if (GetString (&str, 1) == 0) - return 0; - - if (str >= '1' && str <= optionCount + '0') - return str - '0'; - - Beep(); - PrintBackspace(); - } -} - - -static byte AskPassword (Password &password, int& pim) -{ - size_t pos = 0; - byte scanCode; - byte asciiCode; - byte hidePassword = 1; - - pim = 0; - - Print ("Enter password"); - Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": "); - - while (true) - { - asciiCode = GetKeyboardChar (&scanCode); - - switch (scanCode) - { - case TC_BIOS_KEY_ENTER: - password.Length = pos; - Print ("\r"); - if (!PreventNormalSystemBoot) - Print ("Enter password: "); - pos = 0; - while (pos < MAX_PASSWORD) - { - pos++; - if (pos < MAX_PASSWORD) - PrintChar ('*'); - else - PrintCharAtCursor ('*'); - } - - ClearBiosKeystrokeBuffer(); - PrintEndl(); - - break; - - case TC_BIOS_KEY_BACKSPACE: - if (pos > 0) - { - if (pos < MAX_PASSWORD) - PrintBackspace(); - else - PrintCharAtCursor (' '); - - --pos; - } - continue; - - case TC_BIOS_KEY_F5: - hidePassword ^= 0x01; - continue; - - default: - if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode)) - { - burn (password.Text, sizeof (password.Text)); - ClearBiosKeystrokeBuffer(); - - PrintEndl(); - return scanCode; - } - } - - if (TC_BIOS_KEY_ENTER == scanCode) - break; - - if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD) - { - Beep(); - continue; - } - - password.Text[pos++] = asciiCode; - if (hidePassword) asciiCode = '*'; - if (pos < MAX_PASSWORD) - PrintChar (asciiCode); - else - PrintCharAtCursor (asciiCode); - } - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1) - { - pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart; - // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong - PimValueOrHiddenVolumeStartUnitNo.LowPart = -1; - return TC_BIOS_KEY_ENTER; - } - else -#endif - { - pos = 0; - Print ("PIM: "); - - while (true) - { - asciiCode = GetKeyboardChar (&scanCode); - - switch (scanCode) - { - case TC_BIOS_KEY_ENTER: - Print ("\rPIM: "); - pos =0; - while (pos < MAX_PIM) - { - PrintChar ('*'); - pos++; - } - - ClearBiosKeystrokeBuffer(); - PrintEndl(); - - return TC_BIOS_KEY_ENTER; - - case TC_BIOS_KEY_BACKSPACE: - if (pos > 0) - { - if (pos < MAX_PIM) - PrintBackspace(); - else - PrintCharAtCursor (' '); - - --pos; - pim /= 10; - } - continue; - - case TC_BIOS_KEY_F5: - hidePassword ^= 0x01; - continue; - - default: - if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode)) - { - burn (password.Text, sizeof (password.Text)); - ClearBiosKeystrokeBuffer(); - - PrintEndl(); - return scanCode; - } - } - - if (!IsDigit (asciiCode) || pos == MAX_PIM) - { - Beep(); - continue; - } - - pim = 10*pim + (asciiCode - '0'); - pos++; - - if (hidePassword) asciiCode = '*'; - if (pos < MAX_PIM) - PrintChar (asciiCode); - else - PrintCharAtCursor (asciiCode); - } - } -} - - -static void ExecuteBootSector (byte drive, byte *sectorBuffer) -{ - Print ("Booting...\r\n"); - CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE); - - BootStarted = true; - - uint32 addr = 0x7c00; - __asm - { - cli - mov dl, drive // Boot drive - mov dh, 0 - xor ax, ax - mov si, ax - mov ds, ax - mov es, ax - mov ss, ax - mov sp, 0x7c00 - sti - - jmp cs:addr - } -} - - -static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden) -{ - int volumeType; - bool hiddenVolume; - uint64 headerSec; - - AcquireSectorBuffer(); - - for (volumeType = 1; volumeType <= 2; ++volumeType) - { - hiddenVolume = (volumeType == 2); - - if (hiddenVolume) - { - if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount) - continue; - - headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE; - } - else - { - if (skipNormal) - continue; - - headerSec.HighPart = 0; - headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; - } - - if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess) - continue; - - if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS) - { - // Prevent opening a non-system hidden volume - if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)) - { - crypto_close (*cryptoInfo); - continue; - } - - if (headerSaltCrc32) - *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE); - - break; - } - } - - ReleaseSectorBuffer(); - return volumeType != 3; -} - - -static bool CheckMemoryRequirements () -{ - uint16 codeSeg; - __asm mov codeSeg, cs - if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT) - { - PrintErrorNoEndl ("BIOS reserved too much memory: "); - - uint16 memFree; - __asm - { - push es - xor ax, ax - mov es, ax - mov ax, es:[0x413] - mov memFree, ax - pop es - } - - Print (memFree); - PrintEndl(); - Print (TC_BOOT_STR_UPGRADE_BIOS); - - return false; - } - - return true; -} - - -static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden) -{ - BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; - int incorrectPasswordCount = 0, pim = 0; - - EraseMemory (bootArguments, sizeof (*bootArguments)); - - // Open volume header - while (true) - { - exitKey = AskPassword (bootArguments->BootPassword, pim); - - if (exitKey != TC_BIOS_KEY_ENTER) - return false; - - Print ("Verifying password..."); - - if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden)) - { - Print ("OK\r\n"); - break; - } - if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK) - Print ("Warning: Caps Lock is on.\r\n"); - - Print ("Incorrect password.\r\n\r\n"); - - if (++incorrectPasswordCount == 4) - { -#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - Print ("If you are sure the password is correct, the key data may be damaged.\r\n" - "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n"); -#else - Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n" - "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n"); -#endif - } - } - - // Setup boot arguments - bootArguments->BootLoaderVersion = VERSION_NUM; - bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo; - bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo); - bootArguments->Flags = (((uint32)pim) << 16); - - if (BootCryptoInfo->hiddenVolume) - bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR; - - if (ExtraBootPartitionPresent) - bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION; - - TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature); - - // Setup virtual encrypted partition - if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0) - { - EncryptedVirtualPartition.Drive = BootDrive; - - EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; - - PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector; - HiddenVolumeStartSector = PartitionFollowingActive.StartSector; - HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector; - - EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; - - EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1; - EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector; - } - else - { - // Drive not encrypted - EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE; - } - - return true; -} - - -static bool GetSystemPartitions (byte drive) -{ - size_t partCount; - - if (!GetActivePartition (drive)) - return false; - - // Find partition following the active one - GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition); - - // If there is an extra boot partition, use the partitions following it. - // The real boot partition is determined in BootEncryptedDrive(). - if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE - && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE) - { - ExtraBootPartitionPresent = true; - - ActivePartition = PartitionFollowingActive; - GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition); - } - - return true; -} - - -static byte BootEncryptedDrive () -{ - BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; - byte exitKey; - BootCryptoInfo = NULL; - - if (!GetSystemPartitions (BootDrive)) - goto err; - - if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false)) - return exitKey; - - if (!CheckMemoryRequirements ()) - goto err; - - if (BootCryptoInfo->hiddenVolume) - { - EncryptedVirtualPartition = ActivePartition; - bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR; - } - - if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive)) - goto err; - - if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess) - goto err; - - bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8); - - if (!InstallInterruptFilters()) - goto err; - - bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments); - - while (true) - { - // Execute boot sector of the active partition - if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess) - { - if (*(uint16 *) (SectorBuffer + 510) != 0xaa55) - { - PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); - GetKeyboardChar(); - } - - ExecuteBootSector (ActivePartition.Drive, SectorBuffer); - } - - GetKeyboardChar(); - } - -err: - if (BootCryptoInfo) - { - crypto_close (BootCryptoInfo); - BootCryptoInfo = NULL; - } - - EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE; - EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments)); - - byte scanCode; - GetKeyboardChar (&scanCode); - return scanCode; -} - - -static void BootMenu () -{ - BiosResult result; - Partition partitions[16]; - Partition bootablePartitions[9]; - size_t partitionCount; - size_t bootablePartitionCount = 0; - - for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive) - { - if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess) - { - for (size_t i = 0; i < partitionCount; ++i) - { - const Partition &partition = partitions[i]; - result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1); - - if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55) - { - // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore, - // NTFS/FAT partitions must have the boot indicator set to be considered bootable. - if (!partition.Active - && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS' - || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT' - || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT' - || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T')) - { - continue; - } - - // Bootable sector found - if (bootablePartitionCount < array_capacity (bootablePartitions)) - bootablePartitions[bootablePartitionCount++] = partition; - } - } - } - } - - if (bootablePartitionCount < 1) - { - PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); - GetKeyboardChar(); - return; - } - - char partChar; - while (true) - { - InitScreen(); - Print ("Bootable Partitions:\r\n"); - PrintRepeatedChar ('\xC4', 20); - Print ("\r\n"); - - for (size_t i = 0; i < bootablePartitionCount; ++i) - { - const Partition &partition = bootablePartitions[i]; - Print ("["); Print (i + 1); Print ("] "); - Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE); - Print (", Partition: "); Print (partition.Number + 1); - Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl(); - } - - if (bootablePartitionCount == 1) - { - // There's only one bootable partition so we'll boot it directly instead of showing boot manager - partChar = '1'; - } - else - { - Print ("[Esc] Cancel\r\n\r\n"); - Print ("Press 1-9 to select partition: "); - - if (GetString (&partChar, 1) == 0) - return; - - PrintEndl(); - - if (partChar < '1' || partChar > '0' + bootablePartitionCount) - { - Beep(); - continue; - } - } - - const Partition &partition = bootablePartitions[partChar - '0' - 1]; - - if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess) - { - ExecuteBootSector (partition.Drive, SectorBuffer); - } - } -} - - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - -static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey) -{ - bool status = false; - - uint64 sectorsRemaining; - uint64 sectorOffset; - sectorOffset.LowPart = 0; - sectorOffset.HighPart = 0; - - int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS - int statCount = 0; - - if (!CheckMemoryRequirements ()) - goto err; - - if (!GetSystemPartitions (drive)) - goto err; - - if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE) - TC_THROW_FATAL_EXCEPTION; - - // Check if BIOS can read the last sector of the hidden system - AcquireSectorBuffer(); - - if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess - || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc) - { - PrintErrorNoEndl ("Your BIOS does not support large drives"); - Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS"); - PrintEndl(); - Print (TC_BOOT_STR_UPGRADE_BIOS); - - ReleaseSectorBuffer(); - goto err; - } - - ReleaseSectorBuffer(); - - if (!MountVolume (drive, exitKey, true, false)) - return false; - - sectorsRemaining = EncryptedVirtualPartition.SectorCount; - - if (!(sectorsRemaining == ActivePartition.SectorCount)) - TC_THROW_FATAL_EXCEPTION; - - InitScreen(); - Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n"); - - while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0) - { - if (EscKeyPressed()) - { - Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n"); - if (AskYesNo ("Abort")) - break; - } - - if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount) - fragmentSectorCount = (int) sectorsRemaining.LowPart; - - if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess) - { - Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n"); - crypto_close (BootCryptoInfo); - goto err; - } - - AcquireSectorBuffer(); - - for (int i = 0; i < fragmentSectorCount; ++i) - { - CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE); - - uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i; - EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo); - - CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE); - } - - ReleaseSectorBuffer(); - - if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess) - { - crypto_close (BootCryptoInfo); - goto err; - } - - sectorsRemaining = sectorsRemaining - fragmentSectorCount; - sectorOffset = sectorOffset + fragmentSectorCount; - - if (!(statCount++ & 0xf)) - { - Print ("\rRemaining: "); - PrintSectorCountInMB (sectorsRemaining); - } - } - - crypto_close (BootCryptoInfo); - - if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0) - { - status = true; - Print ("\rCopying completed."); - } - - PrintEndl (2); - goto ret; - -err: - exitKey = TC_BIOS_KEY_ESC; - GetKeyboardChar(); - -ret: - EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments)); - return status; -} - - -#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - -static void DecryptDrive (byte drive) -{ - byte exitKey; - if (!MountVolume (drive, exitKey, false, true)) - return; - - BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; - - bool headerUpdateRequired = false; - uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector; - uint64 sector = EncryptedVirtualPartition.EndSector + 1; - - int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS - int statCount = 0; - - bool skipBadSectors = false; - - Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n" - "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n"); - - if (!AskYesNo ("Decrypt now")) - { - crypto_close (BootCryptoInfo); - goto ret; - } - - if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE) - { - // Drive already decrypted - sectorsRemaining.HighPart = 0; - sectorsRemaining.LowPart = 0; - } - else - { - Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n" - "WARNING: You can turn off power only after you press Esc.\r\n\r\n"); - } - - while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0) - { - if (EscKeyPressed()) - break; - - if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount) - fragmentSectorCount = (int) sectorsRemaining.LowPart; - - sector = sector - fragmentSectorCount; - - if (!(statCount++ & 0xf)) - { - Print ("\rRemaining: "); - PrintSectorCountInMB (sectorsRemaining); - } - - if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess) - { - AcquireSectorBuffer(); - - for (int i = 0; i < fragmentSectorCount; ++i) - { - CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE); - - uint64 s = sector + i; - DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo); - - CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE); - } - - ReleaseSectorBuffer(); - - if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors) - goto askBadSectorSkip; - } - else if (!skipBadSectors) - goto askBadSectorSkip; - - sectorsRemaining = sectorsRemaining - fragmentSectorCount; - headerUpdateRequired = true; - continue; - -askBadSectorSkip: - if (!AskYesNo ("Skip all bad sectors")) - break; - - skipBadSectors = true; - sector = sector + fragmentSectorCount; - fragmentSectorCount = 1; - } - - crypto_close (BootCryptoInfo); - - if (headerUpdateRequired) - { - Print ("\rUpdating header..."); - - AcquireSectorBuffer(); - uint64 headerSector; - headerSector.HighPart = 0; - headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; - - // Update encrypted area size in volume header - - CRYPTO_INFO *headerCryptoInfo = crypto_open(); - while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess); - - if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0) - { - DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); - - uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR; - - for (int i = 7; i >= 0; --i) - { - SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart; - encryptedAreaLength = encryptedAreaLength >> 8; - } - - uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); - - for (i = 3; i >= 0; --i) - { - SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32; - headerCrc32 >>= 8; - } - - EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); - } - - crypto_close (headerCryptoInfo); - - while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess); - ReleaseSectorBuffer(); - - Print ("Done!\r\n"); - } - - if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0) - Print ("\rDrive decrypted.\r\n"); - else - Print ("\r\nDecryption deferred.\r\n"); - - GetKeyboardChar(); -ret: - EraseMemory (bootArguments, sizeof (*bootArguments)); -} - - -static void RepairMenu () -{ - DriveGeometry bootLoaderDriveGeometry; - - if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess) - { - // Some BIOSes may fail to get the geometry of an emulated floppy drive - bootLoaderDriveGeometry.Cylinders = 80; - bootLoaderDriveGeometry.Heads = 2; - bootLoaderDriveGeometry.Sectors = 18; - } - - while (true) - { - InitScreen(); - Print ("Available "); Print ("Repair Options"); Print (":\r\n"); - PrintRepeatedChar ('\xC4', 25); - PrintEndl(); - - enum - { - RestoreNone = 0, - DecryptVolume, - RestoreTrueCryptLoader, - RestoreVolumeHeader, - RestoreOriginalSystemLoader - }; - - static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" }; - - int selection = AskSelection (options, - (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1); - - PrintEndl(); - - switch (selection) - { - case RestoreNone: - return; - - case DecryptVolume: - DecryptDrive (BootDrive); - continue; - - case RestoreOriginalSystemLoader: - if (!AskYesNo ("Is the system partition/drive decrypted")) - { - Print ("Please decrypt it first.\r\n"); - GetKeyboardChar(); - continue; - } - break; - } - - bool writeConfirmed = false; - BiosResult result; - - uint64 sector; - sector.HighPart = 0; - ChsAddress chs; - - byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE]; - AcquireSectorBuffer(); - - for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR); - i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i) - { - sector.LowPart = i; - - if (selection == RestoreOriginalSystemLoader) - sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR; - else if (selection == RestoreTrueCryptLoader) - sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR; - - // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used. - // Therefore, only CHS addressing can be used. - LbaToChs (bootLoaderDriveGeometry, sector, chs); - sector.LowPart = i; - - if (i == TC_MBR_SECTOR) - { - // Read current partition table - result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1); - if (result != BiosResultSuccess) - goto err; - - memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable)); - } - - result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1); - if (result != BiosResultSuccess) - goto err; - - if (i == TC_MBR_SECTOR) - { - // Preserve current partition table - memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable)); - } - - // Volume header - if (i == TC_BOOT_VOLUME_HEADER_SECTOR) - { - if (selection == RestoreTrueCryptLoader) - continue; - - if (selection == RestoreVolumeHeader) - { - while (true) - { - bool validHeaderPresent = false; - uint32 masterKeyScheduleCrc; - - Password password; - int pim; - byte exitKey = AskPassword (password, pim); - - if (exitKey != TC_BIOS_KEY_ENTER) - goto abort; - - CRYPTO_INFO *cryptoInfo; - - CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE); - ReleaseSectorBuffer(); - - // Restore volume header only if the current one cannot be used - if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true)) - { - validHeaderPresent = true; - masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)); - crypto_close (cryptoInfo); - } - - AcquireSectorBuffer(); - CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE); - - if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0) - { - if (validHeaderPresent) - { - if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks))) - { - Print ("Original header preserved.\r\n"); - goto err; - } - - Print ("WARNING: Drive 0 contains a valid header!\r\n"); - } - - crypto_close (cryptoInfo); - break; - } - - Print ("Incorrect password.\r\n\r\n"); - } - } - } - - if (!writeConfirmed && !AskYesNo ("Modify drive 0")) - goto abort; - writeConfirmed = true; - - if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess) - goto err; - } -done: - switch (selection) - { - case RestoreTrueCryptLoader: - Print ("VeraCrypt Boot Loader"); - break; - - case RestoreVolumeHeader: - Print ("Header"); - break; - - case RestoreOriginalSystemLoader: - Print ("System loader"); - break; - } - Print (" restored.\r\n"); - -err: GetKeyboardChar(); -abort: ReleaseSectorBuffer(); - } -} - -#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - -#ifndef DEBUG -extern "C" void _acrtused () { } // Required by linker -#endif - - -void main () -{ - __asm mov BootLoaderDrive, dl - __asm mov BootSectorFlags, dh - -#ifdef TC_BOOT_TRACING_ENABLED - InitDebugPort(); -#endif - -#ifdef TC_BOOT_STACK_CHECKING_ENABLED - InitStackChecker(); -#endif - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - ReadBootSectorUserConfiguration(); -#elif defined (TC_WINDOWS_BOOT_AES) - EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION)); -#endif - - InitVideoMode(); - InitScreen(); - - // Determine boot drive - BootDrive = BootLoaderDrive; - if (BootDrive < TC_FIRST_BIOS_DRIVE) - BootDrive = TC_FIRST_BIOS_DRIVE; - - // Query boot drive geometry - if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess) - { - BootDrive = TC_FIRST_BIOS_DRIVE; - if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess) - { -#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - Print ("- Connect system drive to (SATA) port 1\r\n"); -#endif - GetKeyboardChar(); - } - else - BootDriveGeometryValid = true; - } - else - BootDriveGeometryValid = true; - -#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - // Check whether the user is not using the Rescue Disk to create a hidden system - - if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess - && *(uint32 *) (SectorBuffer + 6) == 0x61726556 - && *(uint32 *) (SectorBuffer + 10) == 0x70797243 - && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE) - { - PrintError ("It appears you are creating a hidden OS."); - if (AskYesNo ("Is this correct")) - { - Print ("Please remove the Rescue Disk from the drive and restart."); - while (true); - } - } - -#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - - // Main menu - - while (true) - { - byte exitKey; - InitScreen(); - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - // Hidden system setup - byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE; - - if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE) - { - PreventNormalSystemBoot = true; - PrintMainMenu(); - - if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING) - { - if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey)) - { - BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING; - UpdateBootSectorConfiguration (BootLoaderDrive); - } - else if (exitKey == TC_BIOS_KEY_ESC) - goto bootMenu; - else - continue; - } - } - else - PrintMainMenu(); - - exitKey = BootEncryptedDrive(); - -#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - PrintMainMenu(); - exitKey = BootEncryptedDrive(); - - if (exitKey == TC_MENU_KEY_REPAIR) - { - RepairMenu(); - continue; - } - -#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE - -bootMenu: - if (!PreventBootMenu) - BootMenu(); - } -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Crc.h" +#include "Crypto.h" +#include "Password.h" +#include "Volumes.h" + +#include "Platform.h" +#include "Bios.h" +#include "BootConfig.h" +#include "BootMain.h" +#include "BootDefs.h" +#include "BootCommon.h" +#include "BootConsoleIo.h" +#include "BootDebug.h" +#include "BootDiskIo.h" +#include "BootEncryptedIo.h" +#include "BootMemory.h" +#include "BootStrings.h" +#include "IntFilter.h" + + +static void InitScreen () +{ + ClearScreen(); + + const char *title = +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + " VeraCrypt Boot Loader " +#else + " VeraCrypt Rescue Disk " +#endif + VERSION_STRING "\r\n"; + + Print (title); + + PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE); + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + if (CustomUserMessage[0]) + { + PrintEndl(); + Print (CustomUserMessage); + } +#endif + + PrintEndl (2); +} + + +static void PrintMainMenu () +{ + if (PreventBootMenu) + return; + + Print (" Keyboard Controls:\r\n"); + Print (" [F5] Hide/Show Password and PIM\r\n"); + Print (" [Esc] "); + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE + ? "Boot Non-Hidden System (Boot Manager)" + : "Skip Authentication (Boot Manager)"); + +#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + Print ("Skip Authentication (Boot Manager)"); + Print ("\r\n [F8] "); Print ("Repair Options"); + +#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + PrintEndl (3); +} + + +static bool IsMenuKey (byte scanCode) +{ +#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + return scanCode == TC_MENU_KEY_REPAIR; +#else + return false; +#endif +} + + +static bool AskYesNo (const char *message) +{ + Print (message); + Print ("? (y/n): "); + while (true) + { + switch (GetKeyboardChar()) + { + case 'y': + case 'Y': + case 'z': + case 'Z': + Print ("y\r\n"); + return true; + + case 'n': + case 'N': + Print ("n\r\n"); + return false; + + default: + Beep(); + } + } +} + + +static int AskSelection (const char *options[], size_t optionCount) +{ + for (int i = 0; i < optionCount; ++i) + { + Print ("["); Print (i + 1); Print ("] "); + Print (options[i]); + PrintEndl(); + } + Print ("[Esc] Cancel\r\n\r\n"); + + Print ("To select, press 1-9: "); + + char str; + + while (true) + { + if (GetString (&str, 1) == 0) + return 0; + + if (str >= '1' && str <= optionCount + '0') + return str - '0'; + + Beep(); + PrintBackspace(); + } +} + + +static byte AskPassword (Password &password, int& pim) +{ + size_t pos = 0; + byte scanCode; + byte asciiCode; + byte hidePassword = 1; + + pim = 0; + + Print ("Enter password"); + Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": "); + + while (true) + { + asciiCode = GetKeyboardChar (&scanCode); + + switch (scanCode) + { + case TC_BIOS_KEY_ENTER: + password.Length = pos; + Print ("\r"); + if (!PreventNormalSystemBoot) + Print ("Enter password: "); + pos = 0; + while (pos < MAX_PASSWORD) + { + pos++; + if (pos < MAX_PASSWORD) + PrintChar ('*'); + else + PrintCharAtCursor ('*'); + } + + ClearBiosKeystrokeBuffer(); + PrintEndl(); + + break; + + case TC_BIOS_KEY_BACKSPACE: + if (pos > 0) + { + if (pos < MAX_PASSWORD) + PrintBackspace(); + else + PrintCharAtCursor (' '); + + --pos; + } + continue; + + case TC_BIOS_KEY_F5: + hidePassword ^= 0x01; + continue; + + default: + if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode)) + { + burn (password.Text, sizeof (password.Text)); + ClearBiosKeystrokeBuffer(); + + PrintEndl(); + return scanCode; + } + } + + if (TC_BIOS_KEY_ENTER == scanCode) + break; + + if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD) + { + Beep(); + continue; + } + + password.Text[pos++] = asciiCode; + if (hidePassword) asciiCode = '*'; + if (pos < MAX_PASSWORD) + PrintChar (asciiCode); + else + PrintCharAtCursor (asciiCode); + } + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1) + { + pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart; + // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong + PimValueOrHiddenVolumeStartUnitNo.LowPart = -1; + return TC_BIOS_KEY_ENTER; + } + else +#endif + { + pos = 0; + Print ("PIM: "); + + while (true) + { + asciiCode = GetKeyboardChar (&scanCode); + + switch (scanCode) + { + case TC_BIOS_KEY_ENTER: + Print ("\rPIM: "); + pos =0; + while (pos < MAX_PIM) + { + PrintChar ('*'); + pos++; + } + + ClearBiosKeystrokeBuffer(); + PrintEndl(); + + return TC_BIOS_KEY_ENTER; + + case TC_BIOS_KEY_BACKSPACE: + if (pos > 0) + { + if (pos < MAX_PIM) + PrintBackspace(); + else + PrintCharAtCursor (' '); + + --pos; + pim /= 10; + } + continue; + + case TC_BIOS_KEY_F5: + hidePassword ^= 0x01; + continue; + + default: + if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode)) + { + burn (password.Text, sizeof (password.Text)); + ClearBiosKeystrokeBuffer(); + + PrintEndl(); + return scanCode; + } + } + + if (!IsDigit (asciiCode) || pos == MAX_PIM) + { + Beep(); + continue; + } + + pim = 10*pim + (asciiCode - '0'); + pos++; + + if (hidePassword) asciiCode = '*'; + if (pos < MAX_PIM) + PrintChar (asciiCode); + else + PrintCharAtCursor (asciiCode); + } + } +} + + +static void ExecuteBootSector (byte drive, byte *sectorBuffer) +{ + Print ("Booting...\r\n"); + CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE); + + BootStarted = true; + + uint32 addr = 0x7c00; + __asm + { + cli + mov dl, drive // Boot drive + mov dh, 0 + xor ax, ax + mov si, ax + mov ds, ax + mov es, ax + mov ss, ax + mov sp, 0x7c00 + sti + + jmp cs:addr + } +} + + +static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden) +{ + int volumeType; + bool hiddenVolume; + uint64 headerSec; + + AcquireSectorBuffer(); + + for (volumeType = 1; volumeType <= 2; ++volumeType) + { + hiddenVolume = (volumeType == 2); + + if (hiddenVolume) + { + if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount) + continue; + + headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE; + } + else + { + if (skipNormal) + continue; + + headerSec.HighPart = 0; + headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; + } + + if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess) + continue; + + if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS) + { + // Prevent opening a non-system hidden volume + if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)) + { + crypto_close (*cryptoInfo); + continue; + } + + if (headerSaltCrc32) + *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE); + + break; + } + } + + ReleaseSectorBuffer(); + return volumeType != 3; +} + + +static bool CheckMemoryRequirements () +{ + uint16 codeSeg; + __asm mov codeSeg, cs + if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT) + { + PrintErrorNoEndl ("BIOS reserved too much memory: "); + + uint16 memFree; + __asm + { + push es + xor ax, ax + mov es, ax + mov ax, es:[0x413] + mov memFree, ax + pop es + } + + Print (memFree); + PrintEndl(); + Print (TC_BOOT_STR_UPGRADE_BIOS); + + return false; + } + + return true; +} + + +static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden) +{ + BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; + int incorrectPasswordCount = 0, pim = 0; + + EraseMemory (bootArguments, sizeof (*bootArguments)); + + // Open volume header + while (true) + { + exitKey = AskPassword (bootArguments->BootPassword, pim); + + if (exitKey != TC_BIOS_KEY_ENTER) + return false; + + Print ("Verifying password..."); + + if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden)) + { + Print ("OK\r\n"); + break; + } + if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK) + Print ("Warning: Caps Lock is on.\r\n"); + + Print ("Incorrect password.\r\n\r\n"); + + if (++incorrectPasswordCount == 4) + { +#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + Print ("If you are sure the password is correct, the key data may be damaged.\r\n" + "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n"); +#else + Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n" + "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n"); +#endif + } + } + + // Setup boot arguments + bootArguments->BootLoaderVersion = VERSION_NUM; + bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo; + bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo); + bootArguments->Flags = (((uint32)pim) << 16); + + if (BootCryptoInfo->hiddenVolume) + bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR; + + if (ExtraBootPartitionPresent) + bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION; + + TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature); + + // Setup virtual encrypted partition + if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0) + { + EncryptedVirtualPartition.Drive = BootDrive; + + EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; + + PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector; + HiddenVolumeStartSector = PartitionFollowingActive.StartSector; + HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector; + + EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR; + + EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1; + EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector; + } + else + { + // Drive not encrypted + EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE; + } + + return true; +} + + +static bool GetSystemPartitions (byte drive) +{ + size_t partCount; + + if (!GetActivePartition (drive)) + return false; + + // Find partition following the active one + GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition); + + // If there is an extra boot partition, use the partitions following it. + // The real boot partition is determined in BootEncryptedDrive(). + if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE + && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE) + { + ExtraBootPartitionPresent = true; + + ActivePartition = PartitionFollowingActive; + GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition); + } + + return true; +} + + +static byte BootEncryptedDrive () +{ + BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; + byte exitKey; + BootCryptoInfo = NULL; + + if (!GetSystemPartitions (BootDrive)) + goto err; + + if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false)) + return exitKey; + + if (!CheckMemoryRequirements ()) + goto err; + + if (BootCryptoInfo->hiddenVolume) + { + EncryptedVirtualPartition = ActivePartition; + bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR; + } + + if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive)) + goto err; + + if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess) + goto err; + + bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8); + + if (!InstallInterruptFilters()) + goto err; + + bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments); + + while (true) + { + // Execute boot sector of the active partition + if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess) + { + if (*(uint16 *) (SectorBuffer + 510) != 0xaa55) + { + PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); + GetKeyboardChar(); + } + + ExecuteBootSector (ActivePartition.Drive, SectorBuffer); + } + + GetKeyboardChar(); + } + +err: + if (BootCryptoInfo) + { + crypto_close (BootCryptoInfo); + BootCryptoInfo = NULL; + } + + EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE; + EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments)); + + byte scanCode; + GetKeyboardChar (&scanCode); + return scanCode; +} + + +static void BootMenu () +{ + BiosResult result; + Partition partitions[16]; + Partition bootablePartitions[9]; + size_t partitionCount; + size_t bootablePartitionCount = 0; + + for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive) + { + if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess) + { + for (size_t i = 0; i < partitionCount; ++i) + { + const Partition &partition = partitions[i]; + result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1); + + if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55) + { + // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore, + // NTFS/FAT partitions must have the boot indicator set to be considered bootable. + if (!partition.Active + && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS' + || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT' + || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT' + || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T')) + { + continue; + } + + // Bootable sector found + if (bootablePartitionCount < array_capacity (bootablePartitions)) + bootablePartitions[bootablePartitionCount++] = partition; + } + } + } + } + + if (bootablePartitionCount < 1) + { + PrintError (TC_BOOT_STR_NO_BOOT_PARTITION); + GetKeyboardChar(); + return; + } + + char partChar; + while (true) + { + InitScreen(); + Print ("Bootable Partitions:\r\n"); + PrintRepeatedChar ('\xC4', 20); + Print ("\r\n"); + + for (size_t i = 0; i < bootablePartitionCount; ++i) + { + const Partition &partition = bootablePartitions[i]; + Print ("["); Print (i + 1); Print ("] "); + Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE); + Print (", Partition: "); Print (partition.Number + 1); + Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl(); + } + + if (bootablePartitionCount == 1) + { + // There's only one bootable partition so we'll boot it directly instead of showing boot manager + partChar = '1'; + } + else + { + Print ("[Esc] Cancel\r\n\r\n"); + Print ("Press 1-9 to select partition: "); + + if (GetString (&partChar, 1) == 0) + return; + + PrintEndl(); + + if (partChar < '1' || partChar > '0' + bootablePartitionCount) + { + Beep(); + continue; + } + } + + const Partition &partition = bootablePartitions[partChar - '0' - 1]; + + if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess) + { + ExecuteBootSector (partition.Drive, SectorBuffer); + } + } +} + + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + +static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey) +{ + bool status = false; + + uint64 sectorsRemaining; + uint64 sectorOffset; + sectorOffset.LowPart = 0; + sectorOffset.HighPart = 0; + + int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS + int statCount = 0; + + if (!CheckMemoryRequirements ()) + goto err; + + if (!GetSystemPartitions (drive)) + goto err; + + if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE) + TC_THROW_FATAL_EXCEPTION; + + // Check if BIOS can read the last sector of the hidden system + AcquireSectorBuffer(); + + if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess + || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc) + { + PrintErrorNoEndl ("Your BIOS does not support large drives"); + Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS"); + PrintEndl(); + Print (TC_BOOT_STR_UPGRADE_BIOS); + + ReleaseSectorBuffer(); + goto err; + } + + ReleaseSectorBuffer(); + + if (!MountVolume (drive, exitKey, true, false)) + return false; + + sectorsRemaining = EncryptedVirtualPartition.SectorCount; + + if (!(sectorsRemaining == ActivePartition.SectorCount)) + TC_THROW_FATAL_EXCEPTION; + + InitScreen(); + Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n"); + + while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0) + { + if (EscKeyPressed()) + { + Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n"); + if (AskYesNo ("Abort")) + break; + } + + if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount) + fragmentSectorCount = (int) sectorsRemaining.LowPart; + + if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess) + { + Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n"); + crypto_close (BootCryptoInfo); + goto err; + } + + AcquireSectorBuffer(); + + for (int i = 0; i < fragmentSectorCount; ++i) + { + CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE); + + uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i; + EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo); + + CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE); + } + + ReleaseSectorBuffer(); + + if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess) + { + crypto_close (BootCryptoInfo); + goto err; + } + + sectorsRemaining = sectorsRemaining - fragmentSectorCount; + sectorOffset = sectorOffset + fragmentSectorCount; + + if (!(statCount++ & 0xf)) + { + Print ("\rRemaining: "); + PrintSectorCountInMB (sectorsRemaining); + } + } + + crypto_close (BootCryptoInfo); + + if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0) + { + status = true; + Print ("\rCopying completed."); + } + + PrintEndl (2); + goto ret; + +err: + exitKey = TC_BIOS_KEY_ESC; + GetKeyboardChar(); + +ret: + EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments)); + return status; +} + + +#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + +static void DecryptDrive (byte drive) +{ + byte exitKey; + if (!MountVolume (drive, exitKey, false, true)) + return; + + BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET; + + bool headerUpdateRequired = false; + uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector; + uint64 sector = EncryptedVirtualPartition.EndSector + 1; + + int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS + int statCount = 0; + + bool skipBadSectors = false; + + Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n" + "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n"); + + if (!AskYesNo ("Decrypt now")) + { + crypto_close (BootCryptoInfo); + goto ret; + } + + if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE) + { + // Drive already decrypted + sectorsRemaining.HighPart = 0; + sectorsRemaining.LowPart = 0; + } + else + { + Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n" + "WARNING: You can turn off power only after you press Esc.\r\n\r\n"); + } + + while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0) + { + if (EscKeyPressed()) + break; + + if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount) + fragmentSectorCount = (int) sectorsRemaining.LowPart; + + sector = sector - fragmentSectorCount; + + if (!(statCount++ & 0xf)) + { + Print ("\rRemaining: "); + PrintSectorCountInMB (sectorsRemaining); + } + + if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess) + { + AcquireSectorBuffer(); + + for (int i = 0; i < fragmentSectorCount; ++i) + { + CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE); + + uint64 s = sector + i; + DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo); + + CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE); + } + + ReleaseSectorBuffer(); + + if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors) + goto askBadSectorSkip; + } + else if (!skipBadSectors) + goto askBadSectorSkip; + + sectorsRemaining = sectorsRemaining - fragmentSectorCount; + headerUpdateRequired = true; + continue; + +askBadSectorSkip: + if (!AskYesNo ("Skip all bad sectors")) + break; + + skipBadSectors = true; + sector = sector + fragmentSectorCount; + fragmentSectorCount = 1; + } + + crypto_close (BootCryptoInfo); + + if (headerUpdateRequired) + { + Print ("\rUpdating header..."); + + AcquireSectorBuffer(); + uint64 headerSector; + headerSector.HighPart = 0; + headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; + + // Update encrypted area size in volume header + + CRYPTO_INFO *headerCryptoInfo = crypto_open(); + while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess); + + if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0) + { + DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); + + uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR; + + for (int i = 7; i >= 0; --i) + { + SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart; + encryptedAreaLength = encryptedAreaLength >> 8; + } + + uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); + + for (i = 3; i >= 0; --i) + { + SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32; + headerCrc32 >>= 8; + } + + EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo); + } + + crypto_close (headerCryptoInfo); + + while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess); + ReleaseSectorBuffer(); + + Print ("Done!\r\n"); + } + + if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0) + Print ("\rDrive decrypted.\r\n"); + else + Print ("\r\nDecryption deferred.\r\n"); + + GetKeyboardChar(); +ret: + EraseMemory (bootArguments, sizeof (*bootArguments)); +} + + +static void RepairMenu () +{ + DriveGeometry bootLoaderDriveGeometry; + + if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess) + { + // Some BIOSes may fail to get the geometry of an emulated floppy drive + bootLoaderDriveGeometry.Cylinders = 80; + bootLoaderDriveGeometry.Heads = 2; + bootLoaderDriveGeometry.Sectors = 18; + } + + while (true) + { + InitScreen(); + Print ("Available "); Print ("Repair Options"); Print (":\r\n"); + PrintRepeatedChar ('\xC4', 25); + PrintEndl(); + + enum + { + RestoreNone = 0, + DecryptVolume, + RestoreTrueCryptLoader, + RestoreVolumeHeader, + RestoreOriginalSystemLoader + }; + + static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" }; + + int selection = AskSelection (options, + (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1); + + PrintEndl(); + + switch (selection) + { + case RestoreNone: + return; + + case DecryptVolume: + DecryptDrive (BootDrive); + continue; + + case RestoreOriginalSystemLoader: + if (!AskYesNo ("Is the system partition/drive decrypted")) + { + Print ("Please decrypt it first.\r\n"); + GetKeyboardChar(); + continue; + } + break; + } + + bool writeConfirmed = false; + BiosResult result; + + uint64 sector; + sector.HighPart = 0; + ChsAddress chs; + + byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE]; + AcquireSectorBuffer(); + + for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR); + i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i) + { + sector.LowPart = i; + + if (selection == RestoreOriginalSystemLoader) + sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR; + else if (selection == RestoreTrueCryptLoader) + sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR; + + // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used. + // Therefore, only CHS addressing can be used. + LbaToChs (bootLoaderDriveGeometry, sector, chs); + sector.LowPart = i; + + if (i == TC_MBR_SECTOR) + { + // Read current partition table + result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1); + if (result != BiosResultSuccess) + goto err; + + memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable)); + } + + result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1); + if (result != BiosResultSuccess) + goto err; + + if (i == TC_MBR_SECTOR) + { + // Preserve current partition table + memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable)); + } + + // Volume header + if (i == TC_BOOT_VOLUME_HEADER_SECTOR) + { + if (selection == RestoreTrueCryptLoader) + continue; + + if (selection == RestoreVolumeHeader) + { + while (true) + { + bool validHeaderPresent = false; + uint32 masterKeyScheduleCrc; + + Password password; + int pim; + byte exitKey = AskPassword (password, pim); + + if (exitKey != TC_BIOS_KEY_ENTER) + goto abort; + + CRYPTO_INFO *cryptoInfo; + + CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE); + ReleaseSectorBuffer(); + + // Restore volume header only if the current one cannot be used + if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true)) + { + validHeaderPresent = true; + masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)); + crypto_close (cryptoInfo); + } + + AcquireSectorBuffer(); + CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE); + + if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0) + { + if (validHeaderPresent) + { + if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks))) + { + Print ("Original header preserved.\r\n"); + goto err; + } + + Print ("WARNING: Drive 0 contains a valid header!\r\n"); + } + + crypto_close (cryptoInfo); + break; + } + + Print ("Incorrect password.\r\n\r\n"); + } + } + } + + if (!writeConfirmed && !AskYesNo ("Modify drive 0")) + goto abort; + writeConfirmed = true; + + if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess) + goto err; + } +done: + switch (selection) + { + case RestoreTrueCryptLoader: + Print ("VeraCrypt Boot Loader"); + break; + + case RestoreVolumeHeader: + Print ("Header"); + break; + + case RestoreOriginalSystemLoader: + Print ("System loader"); + break; + } + Print (" restored.\r\n"); + +err: GetKeyboardChar(); +abort: ReleaseSectorBuffer(); + } +} + +#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + +#ifndef DEBUG +extern "C" void _acrtused () { } // Required by linker +#endif + + +void main () +{ + __asm mov BootLoaderDrive, dl + __asm mov BootSectorFlags, dh + +#ifdef TC_BOOT_TRACING_ENABLED + InitDebugPort(); +#endif + +#ifdef TC_BOOT_STACK_CHECKING_ENABLED + InitStackChecker(); +#endif + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + ReadBootSectorUserConfiguration(); +#elif defined (TC_WINDOWS_BOOT_AES) + EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION)); +#endif + + InitVideoMode(); + InitScreen(); + + // Determine boot drive + BootDrive = BootLoaderDrive; + if (BootDrive < TC_FIRST_BIOS_DRIVE) + BootDrive = TC_FIRST_BIOS_DRIVE; + + // Query boot drive geometry + if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess) + { + BootDrive = TC_FIRST_BIOS_DRIVE; + if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess) + { +#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + Print ("- Connect system drive to (SATA) port 1\r\n"); +#endif + GetKeyboardChar(); + } + else + BootDriveGeometryValid = true; + } + else + BootDriveGeometryValid = true; + +#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + // Check whether the user is not using the Rescue Disk to create a hidden system + + if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess + && *(uint32 *) (SectorBuffer + 6) == 0x61726556 + && *(uint32 *) (SectorBuffer + 10) == 0x70797243 + && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE) + { + PrintError ("It appears you are creating a hidden OS."); + if (AskYesNo ("Is this correct")) + { + Print ("Please remove the Rescue Disk from the drive and restart."); + while (true); + } + } + +#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + + // Main menu + + while (true) + { + byte exitKey; + InitScreen(); + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + // Hidden system setup + byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE; + + if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE) + { + PreventNormalSystemBoot = true; + PrintMainMenu(); + + if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING) + { + if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey)) + { + BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING; + UpdateBootSectorConfiguration (BootLoaderDrive); + } + else if (exitKey == TC_BIOS_KEY_ESC) + goto bootMenu; + else + continue; + } + } + else + PrintMainMenu(); + + exitKey = BootEncryptedDrive(); + +#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + PrintMainMenu(); + exitKey = BootEncryptedDrive(); + + if (exitKey == TC_MENU_KEY_REPAIR) + { + RepairMenu(); + continue; + } + +#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE + +bootMenu: + if (!PreventBootMenu) + BootMenu(); + } +} diff --git a/src/Boot/Windows/BootMain.h b/src/Boot/Windows/BootMain.h index b6e75fa6..2f212a18 100644 --- a/src/Boot/Windows/BootMain.h +++ b/src/Boot/Windows/BootMain.h @@ -1,34 +1,34 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootMain -#define TC_HEADER_Boot_BootMain - -#include "TCdefs.h" -#include "Platform.h" - -static byte AskPassword (Password &password, int& pim); -static int AskSelection (const char *options[], size_t optionCount); -static bool AskYesNo (const char *message); -static byte BootEncryptedDrive (); -static void BootMenu (); -static void ExecuteBootSector (byte drive, byte *sectorBuffer); -static void InitScreen (); -static bool IsMenuKey (byte scanCode); -static bool MountVolume (byte drive, byte &exitKey); -static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false); -static void PrintMainMenu (); -static void RepairMenu (); - -#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8 - -#endif // TC_HEADER_Boot_BootMain +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootMain +#define TC_HEADER_Boot_BootMain + +#include "TCdefs.h" +#include "Platform.h" + +static byte AskPassword (Password &password, int& pim); +static int AskSelection (const char *options[], size_t optionCount); +static bool AskYesNo (const char *message); +static byte BootEncryptedDrive (); +static void BootMenu (); +static void ExecuteBootSector (byte drive, byte *sectorBuffer); +static void InitScreen (); +static bool IsMenuKey (byte scanCode); +static bool MountVolume (byte drive, byte &exitKey); +static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false); +static void PrintMainMenu (); +static void RepairMenu (); + +#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8 + +#endif // TC_HEADER_Boot_BootMain diff --git a/src/Boot/Windows/BootMemory.cpp b/src/Boot/Windows/BootMemory.cpp index c1dd3833..505b731a 100644 --- a/src/Boot/Windows/BootMemory.cpp +++ b/src/Boot/Windows/BootMemory.cpp @@ -1,86 +1,86 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "BootDefs.h" -#include "BootMemory.h" - -static uint32 MemoryMapContValue; - -static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry) -{ - static const uint32 function = 0x0000E820UL; - static const uint32 magic = 0x534D4150UL; - static const uint32 bufferSize = sizeof (BiosMemoryMapEntry); - - bool carry = false; - uint32 resultMagic; - uint32 resultSize; - - __asm - { - push es - - lea di, function - TC_ASM_MOV_EAX_DI - lea di, MemoryMapContValue - TC_ASM_MOV_EBX_DI - lea di, bufferSize - TC_ASM_MOV_ECX_DI - lea di, magic - TC_ASM_MOV_EDX_DI - lea di, MemoryMapContValue - TC_ASM_MOV_DI_ECX - - // Use alternative segment to prevent memory corruption caused by buggy BIOSes - push TC_BOOT_LOADER_ALT_SEGMENT - pop es - mov di, 0 - - int 0x15 - jnc no_carry - mov carry, true - no_carry: - - lea di, resultMagic - TC_ASM_MOV_DI_EAX - lea di, MemoryMapContValue - TC_ASM_MOV_DI_EBX - lea di, resultSize - TC_ASM_MOV_DI_ECX - - pop es - } - - CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry)); - - // BIOS may set CF at the end of the list - if (carry) - MemoryMapContValue = 0; - - return resultMagic == magic && resultSize == bufferSize; -} - - -bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry) -{ - MemoryMapContValue = 0; - return GetMemoryMapEntry (entry); -} - - -bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry) -{ - if (MemoryMapContValue == 0) - return false; - - return GetMemoryMapEntry (entry); -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "BootDefs.h" +#include "BootMemory.h" + +static uint32 MemoryMapContValue; + +static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry) +{ + static const uint32 function = 0x0000E820UL; + static const uint32 magic = 0x534D4150UL; + static const uint32 bufferSize = sizeof (BiosMemoryMapEntry); + + bool carry = false; + uint32 resultMagic; + uint32 resultSize; + + __asm + { + push es + + lea di, function + TC_ASM_MOV_EAX_DI + lea di, MemoryMapContValue + TC_ASM_MOV_EBX_DI + lea di, bufferSize + TC_ASM_MOV_ECX_DI + lea di, magic + TC_ASM_MOV_EDX_DI + lea di, MemoryMapContValue + TC_ASM_MOV_DI_ECX + + // Use alternative segment to prevent memory corruption caused by buggy BIOSes + push TC_BOOT_LOADER_ALT_SEGMENT + pop es + mov di, 0 + + int 0x15 + jnc no_carry + mov carry, true + no_carry: + + lea di, resultMagic + TC_ASM_MOV_DI_EAX + lea di, MemoryMapContValue + TC_ASM_MOV_DI_EBX + lea di, resultSize + TC_ASM_MOV_DI_ECX + + pop es + } + + CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry)); + + // BIOS may set CF at the end of the list + if (carry) + MemoryMapContValue = 0; + + return resultMagic == magic && resultSize == bufferSize; +} + + +bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry) +{ + MemoryMapContValue = 0; + return GetMemoryMapEntry (entry); +} + + +bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry) +{ + if (MemoryMapContValue == 0) + return false; + + return GetMemoryMapEntry (entry); +} diff --git a/src/Boot/Windows/BootMemory.h b/src/Boot/Windows/BootMemory.h index 0ed0470d..d4ad1561 100644 --- a/src/Boot/Windows/BootMemory.h +++ b/src/Boot/Windows/BootMemory.h @@ -1,28 +1,28 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Platform.h" -#include "Bios.h" - -#pragma pack(1) - -struct BiosMemoryMapEntry -{ - uint64 BaseAddress; - uint64 Length; - uint32 Type; -}; - -#pragma pack() - -bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry); -bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry); +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Platform.h" +#include "Bios.h" + +#pragma pack(1) + +struct BiosMemoryMapEntry +{ + uint64 BaseAddress; + uint64 Length; + uint32 Type; +}; + +#pragma pack() + +bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry); +bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry); diff --git a/src/Boot/Windows/BootSector.asm b/src/Boot/Windows/BootSector.asm index e0049d29..0518414f 100644 --- a/src/Boot/Windows/BootSector.asm +++ b/src/Boot/Windows/BootSector.asm @@ -1,244 +1,244 @@ -; -; Derived from source code of TrueCrypt 7.1a, which is -; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed -; by the TrueCrypt License 3.0. -; -; Modifications and additions to the original source code (contained in this file) -; and all other portions of this file are Copyright (c) 2013-2016 IDRIX -; and are governed by the Apache License 2.0 the full text of which is -; contained in the file License.txt included in VeraCrypt binary and source -; code distribution packages. -; - -.MODEL tiny -.386 -_TEXT SEGMENT USE16 - -INCLUDE BootDefs.i - -ORG 7C00h ; Standard boot sector offset - -start: - ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address). - ; Far jump to the next instruction sets IP to the standard offset 7C00. - db 0EAh ; jmp 0:main - dw main, 0 - -loader_name_msg: - db ' VeraCrypt Boot Loader', 13, 10, 0 - -main: - cli - xor ax, ax - mov ds, ax - mov ss, ax - mov sp, 7C00h - sti - - ; Display boot loader name - test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE - jnz skip_loader_name_msg - - lea si, loader_name_msg - call print -skip_loader_name_msg: - - ; Determine boot loader segment - mov ax, TC_BOOT_LOADER_SEGMENT - - ; Check available memory - cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED - jge memory_ok - - mov ax, TC_BOOT_LOADER_SEGMENT_LOW - - cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED - jge memory_ok - - ; Insufficient memory - mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT - -memory_ok: - mov es, ax - - ; Clear BSS section - xor al, al - mov di, TC_COM_EXECUTABLE_OFFSET - mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1 - cld - rep stosb - - mov ax, es - sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment - mov es, ax - - ; Load decompressor - mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR -retry_backup: - mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - mov bx, TC_COM_EXECUTABLE_OFFSET - call read_sectors - - ; Decompressor checksum - xor ebx, ebx - mov si, TC_COM_EXECUTABLE_OFFSET - mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE - call checksum - push ebx - - ; Load compressed boot loader - mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET - mov cl, TC_BOOT_LOADER_START_SECTOR - mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT - - test backup_loader_used, 1 - jz non_backup - mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - -non_backup: - call read_sectors - - ; Boot loader checksum - pop ebx - mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET - mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] - call checksum - - ; Verify checksum - cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET] - je checksum_ok - - ; Checksum incorrect - try using backup if available - test backup_loader_used, 1 - jnz loader_damaged - - mov backup_loader_used, 1 - mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - - test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] - jnz retry_backup - -loader_damaged: - lea si, loader_damaged_msg - call print - lea si, loader_name_msg - call print - jmp $ -checksum_ok: - - ; Set up decompressor segment - mov ax, es - mov ds, ax - cli - mov ss, ax - mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE - sti - - push dx - - ; Decompress boot loader - mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] - sub cx, TC_GZIP_HEADER_SIZE - push cx ; Compressed data size - push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data - push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size - push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer - - push cs - push decompressor_ret - push es - push TC_COM_EXECUTABLE_OFFSET - retf -decompressor_ret: - - add sp, 8 - pop dx - - ; Restore boot sector segment - push cs - pop ds - - ; Check decompression result - test ax, ax - jz decompression_ok - - lea si, loader_damaged_msg - call print - jmp $ -decompression_ok: - - ; DH = boot sector flags - mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] - - ; Set up boot loader segment - mov ax, es - add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 - mov es, ax - mov ds, ax - cli - mov ss, ax - mov sp, TC_BOOT_LOADER_STACK_TOP - sti - - ; Execute boot loader - push es - push TC_COM_EXECUTABLE_OFFSET - retf - - ; Print string -print: - xor bx, bx - mov ah, 0eh - cld - -@@: lodsb - test al, al - jz print_end - - int 10h - jmp @B - -print_end: - ret - - ; Read sectors of the first cylinder -read_sectors: - mov ch, 0 ; Cylinder - mov dh, 0 ; Head - ; DL = drive number passed from BIOS - mov ah, 2 - int 13h - jnc read_ok - - lea si, disk_error_msg - call print -read_ok: - ret - - ; Calculate checksum -checksum: - push ds - push es - pop ds - xor eax, eax - cld - -@@: lodsb - add ebx, eax - rol ebx, 1 - loop @B - - pop ds - ret - -backup_loader_used db 0 - -disk_error_msg db 'Disk error', 13, 10, 7, 0 -loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0 - -ORG 7C00h + 510 - dw 0AA55h ; Boot sector signature - -_TEXT ENDS -END start +; +; Derived from source code of TrueCrypt 7.1a, which is +; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed +; by the TrueCrypt License 3.0. +; +; Modifications and additions to the original source code (contained in this file) +; and all other portions of this file are Copyright (c) 2013-2016 IDRIX +; and are governed by the Apache License 2.0 the full text of which is +; contained in the file License.txt included in VeraCrypt binary and source +; code distribution packages. +; + +.MODEL tiny +.386 +_TEXT SEGMENT USE16 + +INCLUDE BootDefs.i + +ORG 7C00h ; Standard boot sector offset + +start: + ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address). + ; Far jump to the next instruction sets IP to the standard offset 7C00. + db 0EAh ; jmp 0:main + dw main, 0 + +loader_name_msg: + db ' VeraCrypt Boot Loader', 13, 10, 0 + +main: + cli + xor ax, ax + mov ds, ax + mov ss, ax + mov sp, 7C00h + sti + + ; Display boot loader name + test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE + jnz skip_loader_name_msg + + lea si, loader_name_msg + call print +skip_loader_name_msg: + + ; Determine boot loader segment + mov ax, TC_BOOT_LOADER_SEGMENT + + ; Check available memory + cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED + jge memory_ok + + mov ax, TC_BOOT_LOADER_SEGMENT_LOW + + cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED + jge memory_ok + + ; Insufficient memory + mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT + +memory_ok: + mov es, ax + + ; Clear BSS section + xor al, al + mov di, TC_COM_EXECUTABLE_OFFSET + mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1 + cld + rep stosb + + mov ax, es + sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment + mov es, ax + + ; Load decompressor + mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR +retry_backup: + mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT + mov bx, TC_COM_EXECUTABLE_OFFSET + call read_sectors + + ; Decompressor checksum + xor ebx, ebx + mov si, TC_COM_EXECUTABLE_OFFSET + mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE + call checksum + push ebx + + ; Load compressed boot loader + mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + mov cl, TC_BOOT_LOADER_START_SECTOR + mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT + + test backup_loader_used, 1 + jz non_backup + mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT + mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT + +non_backup: + call read_sectors + + ; Boot loader checksum + pop ebx + mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] + call checksum + + ; Verify checksum + cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET] + je checksum_ok + + ; Checksum incorrect - try using backup if available + test backup_loader_used, 1 + jnz loader_damaged + + mov backup_loader_used, 1 + mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT + + test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] + jnz retry_backup + +loader_damaged: + lea si, loader_damaged_msg + call print + lea si, loader_name_msg + call print + jmp $ +checksum_ok: + + ; Set up decompressor segment + mov ax, es + mov ds, ax + cli + mov ss, ax + mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + sti + + push dx + + ; Decompress boot loader + mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] + sub cx, TC_GZIP_HEADER_SIZE + push cx ; Compressed data size + push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data + push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size + push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer + + push cs + push decompressor_ret + push es + push TC_COM_EXECUTABLE_OFFSET + retf +decompressor_ret: + + add sp, 8 + pop dx + + ; Restore boot sector segment + push cs + pop ds + + ; Check decompression result + test ax, ax + jz decompression_ok + + lea si, loader_damaged_msg + call print + jmp $ +decompression_ok: + + ; DH = boot sector flags + mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] + + ; Set up boot loader segment + mov ax, es + add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 + mov es, ax + mov ds, ax + cli + mov ss, ax + mov sp, TC_BOOT_LOADER_STACK_TOP + sti + + ; Execute boot loader + push es + push TC_COM_EXECUTABLE_OFFSET + retf + + ; Print string +print: + xor bx, bx + mov ah, 0eh + cld + +@@: lodsb + test al, al + jz print_end + + int 10h + jmp @B + +print_end: + ret + + ; Read sectors of the first cylinder +read_sectors: + mov ch, 0 ; Cylinder + mov dh, 0 ; Head + ; DL = drive number passed from BIOS + mov ah, 2 + int 13h + jnc read_ok + + lea si, disk_error_msg + call print +read_ok: + ret + + ; Calculate checksum +checksum: + push ds + push es + pop ds + xor eax, eax + cld + +@@: lodsb + add ebx, eax + rol ebx, 1 + loop @B + + pop ds + ret + +backup_loader_used db 0 + +disk_error_msg db 'Disk error', 13, 10, 7, 0 +loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0 + +ORG 7C00h + 510 + dw 0AA55h ; Boot sector signature + +_TEXT ENDS +END start diff --git a/src/Boot/Windows/BootStrings.h b/src/Boot/Windows/BootStrings.h index dcf197a1..99c4dc4f 100644 --- a/src/Boot/Windows/BootStrings.h +++ b/src/Boot/Windows/BootStrings.h @@ -1,20 +1,20 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_BootStrings -#define TC_HEADER_Boot_BootStrings - -#define TC_BOOT_STR_ERROR "Error: " -#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found" -#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n" - -#endif // TC_HEADER_Boot_BootStrings +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_BootStrings +#define TC_HEADER_Boot_BootStrings + +#define TC_BOOT_STR_ERROR "Error: " +#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found" +#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n" + +#endif // TC_HEADER_Boot_BootStrings diff --git a/src/Boot/Windows/Decompressor.c b/src/Boot/Windows/Decompressor.c index 475a501d..3bed8c67 100644 --- a/src/Boot/Windows/Decompressor.c +++ b/src/Boot/Windows/Decompressor.c @@ -83,7 +83,7 @@ local int stored(struct state *s) s->bitbuf = 0; s->bitcnt = 0; - if (s->incnt + 4 > s->inlen) + if (s->incnt + 4 > s->inlen) return 2; /* not enough input */ /* get length and check against its one's complement */ @@ -93,7 +93,7 @@ local int stored(struct state *s) s->in[s->incnt++] != ((~len >> 8) & 0xff)) return -2; /* didn't match complement! */ - if (s->incnt + len > s->inlen) + if (s->incnt + len > s->inlen) return 2; /* not enough input */ /* copy len bytes from in to out */ @@ -379,21 +379,21 @@ local int dynamic(struct state *s) lengths[index++] = symbol; else { /* repeat instruction */ len = 0; /* assume repeating zeros */ - switch(symbol) - { - case 16: { /* repeat last length 3..6 times */ - if (index == 0) return -5; /* no last length! */ - len = lengths[index - 1]; /* last length */ - symbol = 3 + bits(s, 2); - break; - } - case 17: /* repeat zero 3..10 times */ - symbol = 3 + bits(s, 3); - break; - default: /* == 18, repeat zero 11..138 times */ - symbol = 11 + bits(s, 7); - break; - } + switch(symbol) + { + case 16: { /* repeat last length 3..6 times */ + if (index == 0) return -5; /* no last length! */ + len = lengths[index - 1]; /* last length */ + symbol = 3 + bits(s, 2); + break; + } + case 17: /* repeat zero 3..10 times */ + symbol = 3 + bits(s, 3); + break; + default: /* == 18, repeat zero 11..138 times */ + symbol = 11 + bits(s, 7); + break; + } if ((index + symbol > nlen + ndist)) return -6; /* too many lengths! */ while (symbol--) /* repeat last or zero symbol times */ @@ -401,8 +401,8 @@ local int dynamic(struct state *s) } } - /* check for end-of-block code -- there better be one! */ - if (lengths[256] == 0) + /* check for end-of-block code -- there better be one! */ + if (lengths[256] == 0) return -9; /* build huffman table for literal/length codes */ @@ -423,50 +423,50 @@ local int dynamic(struct state *s) void _acrtused () { } // Decompress deflated data -int far main ( - unsigned char *dest, /* pointer to destination pointer */ - unsigned int destlen, /* amount of output space */ - unsigned char *source, /* pointer to source data pointer */ - unsigned int sourcelen) -{ - struct state s; /* input/output state */ - int last, type; /* block information */ - int err; /* return value */ - - /* initialize output state */ - s.out = dest; - s.outlen = destlen; /* ignored if dest is NIL */ - s.outcnt = 0; - - /* initialize input state */ - s.in = source; - s.inlen = sourcelen; - s.incnt = 0; - s.bitbuf = 0; - s.bitcnt = 0; - - /* process blocks until last block or error */ - do { - last = bits(&s, 1); /* one if last block */ - type = bits(&s, 2); /* block type 0..3 */ - switch(type) - { - case 0: - err = stored(&s); - break; - case 1: - err = fixed(&s); - break; - case 2: - err = dynamic(&s); - break; - default: - err = -1; /* type == 3, invalid */ - break; - } - - if (err != 0) break; /* return with error */ - } while (!last); - - return err; +int far main ( + unsigned char *dest, /* pointer to destination pointer */ + unsigned int destlen, /* amount of output space */ + unsigned char *source, /* pointer to source data pointer */ + unsigned int sourcelen) +{ + struct state s; /* input/output state */ + int last, type; /* block information */ + int err; /* return value */ + + /* initialize output state */ + s.out = dest; + s.outlen = destlen; /* ignored if dest is NIL */ + s.outcnt = 0; + + /* initialize input state */ + s.in = source; + s.inlen = sourcelen; + s.incnt = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* process blocks until last block or error */ + do { + last = bits(&s, 1); /* one if last block */ + type = bits(&s, 2); /* block type 0..3 */ + switch(type) + { + case 0: + err = stored(&s); + break; + case 1: + err = fixed(&s); + break; + case 2: + err = dynamic(&s); + break; + default: + err = -1; /* type == 3, invalid */ + break; + } + + if (err != 0) break; /* return with error */ + } while (!last); + + return err; } diff --git a/src/Boot/Windows/IntFilter.cpp b/src/Boot/Windows/IntFilter.cpp index 0671c4d0..d9cd92df 100644 --- a/src/Boot/Windows/IntFilter.cpp +++ b/src/Boot/Windows/IntFilter.cpp @@ -1,645 +1,645 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Platform.h" -#include "BootMemory.h" -#include "BootConfig.h" -#include "BootConsoleIo.h" -#include "BootDebug.h" -#include "BootDefs.h" -#include "BootDiskIo.h" -#include "BootEncryptedIo.h" -#include "BootStrings.h" -#include "IntFilter.h" - -static uint32 OriginalInt13Handler; -static uint32 OriginalInt15Handler; - -static Registers IntRegisters; - - -bool Int13Filter () -{ - CheckStack(); - - Registers regs; - memcpy (®s, &IntRegisters, sizeof (regs)); - __asm sti - - static int ReEntryCount = -1; - ++ReEntryCount; - - byte function = (byte) (regs.AX >> 8); - -#ifdef TC_TRACE_INT13 - DisableScreenOutput(); - - PrintHex (function); - - Print (" EN:"); Print (ReEntryCount); - Print (" SS:"); PrintHex (regs.SS); - - uint16 spdbg; - __asm mov spdbg, sp - PrintChar (' '); - PrintHex (spdbg); - PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP); - -#endif - - bool passOriginalRequest = true; - - switch (function) - { - case 0x2: // Read sectors - case 0x3: // Write sectors - { - byte drive = (byte) regs.DX; - - ChsAddress chs; - chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8); - chs.Head = regs.DX >> 8; - chs.Sector = regs.CX & 0x3f; - - byte sectorCount = (byte) regs.AX; - -#ifdef TC_TRACE_INT13 - PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false); - Print (" Chs: "); Print (chs); -#endif - - uint64 sector; - if (drive == BootDrive) - { - if (!BootDriveGeometryValid) - TC_THROW_FATAL_EXCEPTION; - - ChsToLba (BootDriveGeometry, chs, sector); -#ifdef TC_TRACE_INT13 - PrintVal (" Sec", sector.LowPart, false); -#endif - } - -#ifdef TC_TRACE_INT13 - PrintVal (" Count", sectorCount, false); - Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX); - PrintEndl(); -#endif - - if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive) - { - BiosResult result; - - if (function == 0x3) - result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount); - else - result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount); - - __asm cli - - memcpy (&IntRegisters, ®s, sizeof (regs)); - IntRegisters.AX = (uint16) result << 8; - - if (result == BiosResultSuccess) - { - IntRegisters.AX |= sectorCount; - IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; - } - else - IntRegisters.Flags |= TC_X86_CARRY_FLAG; - - passOriginalRequest = false; - } - } - break; - - case 0x42: // Read sectors LBA - case 0x43: // Write sectors LBA - { - byte drive = (byte) regs.DX; - - BiosLbaPacket lba; - CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba)); - -#ifdef TC_TRACE_INT13 - PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false); - PrintVal (" Sec", lba.Sector.LowPart, false); - PrintVal (" Count", lba.SectorCount, false); - PrintVal (" Buf", lba.Buffer, false, true); - PrintEndl(); -#endif - - if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive) - { - BiosResult result; - - uint16 segment = (uint16) (lba.Buffer >> 16); - uint16 offset = (uint16) lba.Buffer; - - if (function == 0x43) - result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount); - else - result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount); - - __asm cli - - memcpy (&IntRegisters, ®s, sizeof (regs)); - IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8); - - if (result == BiosResultSuccess) - IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; - else - IntRegisters.Flags |= TC_X86_CARRY_FLAG; - - passOriginalRequest = false; - } - } - break; - - default: -#ifdef TC_TRACE_INT13 - PrintEndl(); -#endif - break; - } - -#ifdef TC_TRACE_INT13 - EnableScreenOutput(); -#endif - --ReEntryCount; - - return passOriginalRequest; -} - - -#define TC_MAX_MEMORY_MAP_SIZE 80 - -BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE]; -static size_t BiosMemoryMapSize; - - -static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart) -{ - newMapEntry->Type = 0x2; - newMapEntry->BaseAddress.HighPart = 0; - newMapEntry->BaseAddress.LowPart = bootLoaderStart; - newMapEntry->Length.HighPart = 0; - newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL; -} - - -static bool CreateNewBiosMemoryMap () -{ - // Create a new BIOS memory map presenting the memory area of the loader as reserved - - BiosMemoryMapSize = 0; - BiosMemoryMapEntry entry; - BiosMemoryMapEntry *newMapEntry = BiosMemoryMap; - - const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE; - - uint64 bootLoaderStart; - bootLoaderStart.HighPart = 0; - - uint16 codeSeg; - __asm mov codeSeg, cs - bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0); - - uint64 bootLoaderEnd; - bootLoaderEnd.HighPart = 0; - bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL; - - bool loaderEntryInserted = false; - - if (GetFirstBiosMemoryMapEntry (entry)) - { - do - { - uint64 entryEnd = entry.BaseAddress + entry.Length; - - if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1)) - { - // Free map entry covers the boot loader area - - if (entry.BaseAddress < bootLoaderStart) - { - // Create free entry below the boot loader area - if (newMapEntry >= mapEnd) - goto mapOverflow; - - *newMapEntry = entry; - newMapEntry->Length = bootLoaderStart - entry.BaseAddress; - ++newMapEntry; - } - - if (!loaderEntryInserted) - { - // Create reserved entry for the boot loader if it has not been done yet - if (newMapEntry >= mapEnd) - goto mapOverflow; - - CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart); - ++newMapEntry; - loaderEntryInserted = true; - } - - if (bootLoaderEnd < entryEnd) - { - // Create free entry above the boot loader area - if (newMapEntry >= mapEnd) - goto mapOverflow; - - newMapEntry->Type = 0x1; - newMapEntry->BaseAddress = bootLoaderEnd; - newMapEntry->Length = entryEnd - bootLoaderEnd; - ++newMapEntry; - } - } - else - { - if (newMapEntry >= mapEnd) - goto mapOverflow; - - if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart) - { - // Create reserved entry for the boot loader if it has not been done yet - CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart); - ++newMapEntry; - loaderEntryInserted = true; - } - - // Copy map entry - *newMapEntry++ = entry; - } - - } while (GetNextBiosMemoryMapEntry (entry)); - } - - BiosMemoryMapSize = newMapEntry - BiosMemoryMap; - return true; - -mapOverflow: - size_t overSize = 0; - while (GetNextBiosMemoryMapEntry (entry)) - { - ++overSize; - } - - PrintErrorNoEndl ("MMP:"); - Print (overSize); - PrintEndl(); - - return false; -} - - -bool Int15Filter () -{ - CheckStack(); - -#ifdef TC_TRACE_INT15 - DisableScreenOutput(); - - Print ("15-"); - PrintHex (IntRegisters.AX); - - Print (" SS:"); PrintHex (IntRegisters.SS); - - uint16 spdbg; - __asm mov spdbg, sp - PrintChar (' '); - PrintHex (spdbg); - PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP); - - Print (" EAX:"); PrintHex (IntRegisters.EAX); - Print (" EBX:"); PrintHex (IntRegisters.EBX); - Print (" ECX:"); PrintHex (IntRegisters.ECX); - Print (" EDX:"); PrintHex (IntRegisters.EDX); - Print (" DI:"); PrintHex (IntRegisters.DI); - PrintEndl(); - -#endif - - if (IntRegisters.EBX >= BiosMemoryMapSize) - { - IntRegisters.Flags |= TC_X86_CARRY_FLAG; - IntRegisters.EBX = 0; - IntRegisters.AX = -1; - } - else - { - CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0])); - - IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; - IntRegisters.EAX = 0x534D4150UL; - - ++IntRegisters.EBX; - if (IntRegisters.EBX >= BiosMemoryMapSize) - IntRegisters.EBX = 0; - - IntRegisters.ECX = sizeof (BiosMemoryMap[0]); - } - - if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER)) - { - // Uninstall filter when the modified map has been issued three times to prevent - // problems with hardware drivers on some notebooks running Windows XP. - - static int CompleteMapIssueCount = 0; - if (++CompleteMapIssueCount >= 3) - { - __asm - { - cli - push es - - lea si, OriginalInt15Handler - xor ax, ax - mov es, ax - mov di, 0x15 * 4 - - mov ax, [si] - mov es:[di], ax - mov ax, [si + 2] - mov es:[di + 2], ax - - pop es - sti - } - } - } - -#ifdef TC_TRACE_INT15 - BiosMemoryMapEntry entry; - CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry)); - PrintHex (entry.Type); PrintChar (' '); - PrintHex (entry.BaseAddress); PrintChar (' '); - PrintHex (entry.Length); PrintChar (' '); - PrintHex (entry.BaseAddress + entry.Length); PrintEndl(); - - Print ("EAX:"); PrintHex (IntRegisters.EAX); - Print (" EBX:"); PrintHex (IntRegisters.EBX); - Print (" ECX:"); PrintHex (IntRegisters.ECX); - Print (" EDX:"); PrintHex (IntRegisters.EDX); - Print (" DI:"); PrintHex (IntRegisters.DI); - Print (" FL:"); PrintHex (IntRegisters.Flags); - PrintEndl (2); -#endif - -#ifdef TC_TRACE_INT15 - EnableScreenOutput(); -#endif - return false; -} - - -void IntFilterEntry () -{ - // No automatic variables should be used in this scope as SS may change - static uint16 OrigStackPointer; - static uint16 OrigStackSegment; - - __asm - { - pushf - pushad - - cli - mov cs:IntRegisters.DI, di - - lea di, cs:IntRegisters.EAX - TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax - lea di, cs:IntRegisters.EBX - TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx - lea di, cs:IntRegisters.ECX - TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx - lea di, cs:IntRegisters.EDX - TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx - - mov ax, [bp + 8] - mov cs:IntRegisters.Flags, ax - - mov cs:IntRegisters.SI, si - mov si, [bp + 2] // Int number - - mov cs:IntRegisters.DS, ds - mov cs:IntRegisters.ES, es - mov cs:IntRegisters.SS, ss - - // Compiler assumes SS == DS - use our stack if this condition is not met - mov ax, ss - mov bx, cs - cmp ax, bx - jz stack_ok - - mov cs:OrigStackPointer, sp - mov cs:OrigStackSegment, ss - mov ax, cs - mov ss, ax - mov sp, TC_BOOT_LOADER_STACK_TOP - - stack_ok: - // DS = CS - push ds - push es - mov ax, cs - mov ds, ax - mov es, ax - - push si // Int number - - // Filter request - cmp si, 0x15 - je filter15 - cmp si, 0x13 - jne $ - - call Int13Filter - jmp s0 - - filter15: - call Int15Filter - - s0: - pop si // Int number - pop es - pop ds - - // Restore original SS:SP if our stack is empty - cli - mov bx, TC_BOOT_LOADER_STACK_TOP - cmp bx, sp - jnz stack_in_use - - mov ss, cs:OrigStackSegment - mov sp, cs:OrigStackPointer - stack_in_use: - - test ax, ax // passOriginalRequest - jnz pass_request - - // Return results of filtered request - popad - popf - mov ax, cs:IntRegisters.Flags - mov [bp + 8], ax - leave - - lea di, cs:IntRegisters.EAX - TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di] - lea di, cs:IntRegisters.EBX - TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di] - lea di, cs:IntRegisters.ECX - TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di] - lea di, cs:IntRegisters.EDX - TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di] - - mov di, cs:IntRegisters.DI - mov si, cs:IntRegisters.SI - mov es, cs:IntRegisters.ES - mov ds, cs:IntRegisters.DS - - sti - add sp, 2 - iret - - // Pass original request - pass_request: - sti - cmp si, 0x15 - je pass15 - cmp si, 0x13 - jne $ - - popad - popf - leave - add sp, 2 - jmp cs:OriginalInt13Handler - - pass15: - popad - popf - leave - add sp, 2 - jmp cs:OriginalInt15Handler - } -} - - -void Int13FilterEntry () -{ - __asm - { - leave - push 0x13 - jmp IntFilterEntry - } -} - - -static void Int15FilterEntry () -{ - __asm - { - pushf - cmp ax, 0xe820 // Get system memory map - je filter - - popf - leave - jmp cs:OriginalInt15Handler - - filter: - leave - push 0x15 - jmp IntFilterEntry - } -} - - -bool InstallInterruptFilters () -{ - -#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE - - // If the filters have already been installed, it usually indicates stack corruption - // and a consequent reentry of this routine without a system reset. - - uint32 currentInt13Handler; - CopyMemory (0, 0x13 * 4, ¤tInt13Handler, sizeof (currentInt13Handler)); - - if (currentInt13Handler == (uint32) Int13FilterEntry) - { - PrintError ("Memory corrupted"); - Print (TC_BOOT_STR_UPGRADE_BIOS); - - GetKeyboardChar(); - return true; - } - -#endif - - if (!CreateNewBiosMemoryMap()) - return false; - - __asm - { - cli - push es - - // Save original INT 13 handler - xor ax, ax - mov es, ax - - mov si, 0x13 * 4 - lea di, OriginalInt13Handler - - mov ax, es:[si] - mov [di], ax - mov ax, es:[si + 2] - mov [di + 2], ax - - // Install INT 13 filter - lea ax, Int13FilterEntry - mov es:[si], ax - mov es:[si + 2], cs - - // Save original INT 15 handler - mov si, 0x15 * 4 - lea di, OriginalInt15Handler - - mov ax, es:[si] - mov [di], ax - mov ax, es:[si + 2] - mov [di + 2], ax - - // Install INT 15 filter - lea ax, Int15FilterEntry - mov es:[si], ax - mov es:[si + 2], cs - - // If the BIOS does not support system memory map (INT15 0xe820), - // set amount of available memory to CS:0000 - 0:0000 - cmp BiosMemoryMapSize, 1 - jg mem_map_ok - mov ax, cs - shr ax, 10 - 4 // CS * 16 / 1024 - mov es:[0x413], ax // = KBytes available - mem_map_ok: - - pop es - sti - } - - return true; -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Platform.h" +#include "BootMemory.h" +#include "BootConfig.h" +#include "BootConsoleIo.h" +#include "BootDebug.h" +#include "BootDefs.h" +#include "BootDiskIo.h" +#include "BootEncryptedIo.h" +#include "BootStrings.h" +#include "IntFilter.h" + +static uint32 OriginalInt13Handler; +static uint32 OriginalInt15Handler; + +static Registers IntRegisters; + + +bool Int13Filter () +{ + CheckStack(); + + Registers regs; + memcpy (®s, &IntRegisters, sizeof (regs)); + __asm sti + + static int ReEntryCount = -1; + ++ReEntryCount; + + byte function = (byte) (regs.AX >> 8); + +#ifdef TC_TRACE_INT13 + DisableScreenOutput(); + + PrintHex (function); + + Print (" EN:"); Print (ReEntryCount); + Print (" SS:"); PrintHex (regs.SS); + + uint16 spdbg; + __asm mov spdbg, sp + PrintChar (' '); + PrintHex (spdbg); + PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP); + +#endif + + bool passOriginalRequest = true; + + switch (function) + { + case 0x2: // Read sectors + case 0x3: // Write sectors + { + byte drive = (byte) regs.DX; + + ChsAddress chs; + chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8); + chs.Head = regs.DX >> 8; + chs.Sector = regs.CX & 0x3f; + + byte sectorCount = (byte) regs.AX; + +#ifdef TC_TRACE_INT13 + PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false); + Print (" Chs: "); Print (chs); +#endif + + uint64 sector; + if (drive == BootDrive) + { + if (!BootDriveGeometryValid) + TC_THROW_FATAL_EXCEPTION; + + ChsToLba (BootDriveGeometry, chs, sector); +#ifdef TC_TRACE_INT13 + PrintVal (" Sec", sector.LowPart, false); +#endif + } + +#ifdef TC_TRACE_INT13 + PrintVal (" Count", sectorCount, false); + Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX); + PrintEndl(); +#endif + + if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive) + { + BiosResult result; + + if (function == 0x3) + result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount); + else + result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount); + + __asm cli + + memcpy (&IntRegisters, ®s, sizeof (regs)); + IntRegisters.AX = (uint16) result << 8; + + if (result == BiosResultSuccess) + { + IntRegisters.AX |= sectorCount; + IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; + } + else + IntRegisters.Flags |= TC_X86_CARRY_FLAG; + + passOriginalRequest = false; + } + } + break; + + case 0x42: // Read sectors LBA + case 0x43: // Write sectors LBA + { + byte drive = (byte) regs.DX; + + BiosLbaPacket lba; + CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba)); + +#ifdef TC_TRACE_INT13 + PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false); + PrintVal (" Sec", lba.Sector.LowPart, false); + PrintVal (" Count", lba.SectorCount, false); + PrintVal (" Buf", lba.Buffer, false, true); + PrintEndl(); +#endif + + if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive) + { + BiosResult result; + + uint16 segment = (uint16) (lba.Buffer >> 16); + uint16 offset = (uint16) lba.Buffer; + + if (function == 0x43) + result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount); + else + result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount); + + __asm cli + + memcpy (&IntRegisters, ®s, sizeof (regs)); + IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8); + + if (result == BiosResultSuccess) + IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; + else + IntRegisters.Flags |= TC_X86_CARRY_FLAG; + + passOriginalRequest = false; + } + } + break; + + default: +#ifdef TC_TRACE_INT13 + PrintEndl(); +#endif + break; + } + +#ifdef TC_TRACE_INT13 + EnableScreenOutput(); +#endif + --ReEntryCount; + + return passOriginalRequest; +} + + +#define TC_MAX_MEMORY_MAP_SIZE 80 + +BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE]; +static size_t BiosMemoryMapSize; + + +static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart) +{ + newMapEntry->Type = 0x2; + newMapEntry->BaseAddress.HighPart = 0; + newMapEntry->BaseAddress.LowPart = bootLoaderStart; + newMapEntry->Length.HighPart = 0; + newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL; +} + + +static bool CreateNewBiosMemoryMap () +{ + // Create a new BIOS memory map presenting the memory area of the loader as reserved + + BiosMemoryMapSize = 0; + BiosMemoryMapEntry entry; + BiosMemoryMapEntry *newMapEntry = BiosMemoryMap; + + const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE; + + uint64 bootLoaderStart; + bootLoaderStart.HighPart = 0; + + uint16 codeSeg; + __asm mov codeSeg, cs + bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0); + + uint64 bootLoaderEnd; + bootLoaderEnd.HighPart = 0; + bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL; + + bool loaderEntryInserted = false; + + if (GetFirstBiosMemoryMapEntry (entry)) + { + do + { + uint64 entryEnd = entry.BaseAddress + entry.Length; + + if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1)) + { + // Free map entry covers the boot loader area + + if (entry.BaseAddress < bootLoaderStart) + { + // Create free entry below the boot loader area + if (newMapEntry >= mapEnd) + goto mapOverflow; + + *newMapEntry = entry; + newMapEntry->Length = bootLoaderStart - entry.BaseAddress; + ++newMapEntry; + } + + if (!loaderEntryInserted) + { + // Create reserved entry for the boot loader if it has not been done yet + if (newMapEntry >= mapEnd) + goto mapOverflow; + + CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart); + ++newMapEntry; + loaderEntryInserted = true; + } + + if (bootLoaderEnd < entryEnd) + { + // Create free entry above the boot loader area + if (newMapEntry >= mapEnd) + goto mapOverflow; + + newMapEntry->Type = 0x1; + newMapEntry->BaseAddress = bootLoaderEnd; + newMapEntry->Length = entryEnd - bootLoaderEnd; + ++newMapEntry; + } + } + else + { + if (newMapEntry >= mapEnd) + goto mapOverflow; + + if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart) + { + // Create reserved entry for the boot loader if it has not been done yet + CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart); + ++newMapEntry; + loaderEntryInserted = true; + } + + // Copy map entry + *newMapEntry++ = entry; + } + + } while (GetNextBiosMemoryMapEntry (entry)); + } + + BiosMemoryMapSize = newMapEntry - BiosMemoryMap; + return true; + +mapOverflow: + size_t overSize = 0; + while (GetNextBiosMemoryMapEntry (entry)) + { + ++overSize; + } + + PrintErrorNoEndl ("MMP:"); + Print (overSize); + PrintEndl(); + + return false; +} + + +bool Int15Filter () +{ + CheckStack(); + +#ifdef TC_TRACE_INT15 + DisableScreenOutput(); + + Print ("15-"); + PrintHex (IntRegisters.AX); + + Print (" SS:"); PrintHex (IntRegisters.SS); + + uint16 spdbg; + __asm mov spdbg, sp + PrintChar (' '); + PrintHex (spdbg); + PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP); + + Print (" EAX:"); PrintHex (IntRegisters.EAX); + Print (" EBX:"); PrintHex (IntRegisters.EBX); + Print (" ECX:"); PrintHex (IntRegisters.ECX); + Print (" EDX:"); PrintHex (IntRegisters.EDX); + Print (" DI:"); PrintHex (IntRegisters.DI); + PrintEndl(); + +#endif + + if (IntRegisters.EBX >= BiosMemoryMapSize) + { + IntRegisters.Flags |= TC_X86_CARRY_FLAG; + IntRegisters.EBX = 0; + IntRegisters.AX = -1; + } + else + { + CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0])); + + IntRegisters.Flags &= ~TC_X86_CARRY_FLAG; + IntRegisters.EAX = 0x534D4150UL; + + ++IntRegisters.EBX; + if (IntRegisters.EBX >= BiosMemoryMapSize) + IntRegisters.EBX = 0; + + IntRegisters.ECX = sizeof (BiosMemoryMap[0]); + } + + if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER)) + { + // Uninstall filter when the modified map has been issued three times to prevent + // problems with hardware drivers on some notebooks running Windows XP. + + static int CompleteMapIssueCount = 0; + if (++CompleteMapIssueCount >= 3) + { + __asm + { + cli + push es + + lea si, OriginalInt15Handler + xor ax, ax + mov es, ax + mov di, 0x15 * 4 + + mov ax, [si] + mov es:[di], ax + mov ax, [si + 2] + mov es:[di + 2], ax + + pop es + sti + } + } + } + +#ifdef TC_TRACE_INT15 + BiosMemoryMapEntry entry; + CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry)); + PrintHex (entry.Type); PrintChar (' '); + PrintHex (entry.BaseAddress); PrintChar (' '); + PrintHex (entry.Length); PrintChar (' '); + PrintHex (entry.BaseAddress + entry.Length); PrintEndl(); + + Print ("EAX:"); PrintHex (IntRegisters.EAX); + Print (" EBX:"); PrintHex (IntRegisters.EBX); + Print (" ECX:"); PrintHex (IntRegisters.ECX); + Print (" EDX:"); PrintHex (IntRegisters.EDX); + Print (" DI:"); PrintHex (IntRegisters.DI); + Print (" FL:"); PrintHex (IntRegisters.Flags); + PrintEndl (2); +#endif + +#ifdef TC_TRACE_INT15 + EnableScreenOutput(); +#endif + return false; +} + + +void IntFilterEntry () +{ + // No automatic variables should be used in this scope as SS may change + static uint16 OrigStackPointer; + static uint16 OrigStackSegment; + + __asm + { + pushf + pushad + + cli + mov cs:IntRegisters.DI, di + + lea di, cs:IntRegisters.EAX + TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax + lea di, cs:IntRegisters.EBX + TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx + lea di, cs:IntRegisters.ECX + TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx + lea di, cs:IntRegisters.EDX + TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx + + mov ax, [bp + 8] + mov cs:IntRegisters.Flags, ax + + mov cs:IntRegisters.SI, si + mov si, [bp + 2] // Int number + + mov cs:IntRegisters.DS, ds + mov cs:IntRegisters.ES, es + mov cs:IntRegisters.SS, ss + + // Compiler assumes SS == DS - use our stack if this condition is not met + mov ax, ss + mov bx, cs + cmp ax, bx + jz stack_ok + + mov cs:OrigStackPointer, sp + mov cs:OrigStackSegment, ss + mov ax, cs + mov ss, ax + mov sp, TC_BOOT_LOADER_STACK_TOP + + stack_ok: + // DS = CS + push ds + push es + mov ax, cs + mov ds, ax + mov es, ax + + push si // Int number + + // Filter request + cmp si, 0x15 + je filter15 + cmp si, 0x13 + jne $ + + call Int13Filter + jmp s0 + + filter15: + call Int15Filter + + s0: + pop si // Int number + pop es + pop ds + + // Restore original SS:SP if our stack is empty + cli + mov bx, TC_BOOT_LOADER_STACK_TOP + cmp bx, sp + jnz stack_in_use + + mov ss, cs:OrigStackSegment + mov sp, cs:OrigStackPointer + stack_in_use: + + test ax, ax // passOriginalRequest + jnz pass_request + + // Return results of filtered request + popad + popf + mov ax, cs:IntRegisters.Flags + mov [bp + 8], ax + leave + + lea di, cs:IntRegisters.EAX + TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di] + lea di, cs:IntRegisters.EBX + TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di] + lea di, cs:IntRegisters.ECX + TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di] + lea di, cs:IntRegisters.EDX + TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di] + + mov di, cs:IntRegisters.DI + mov si, cs:IntRegisters.SI + mov es, cs:IntRegisters.ES + mov ds, cs:IntRegisters.DS + + sti + add sp, 2 + iret + + // Pass original request + pass_request: + sti + cmp si, 0x15 + je pass15 + cmp si, 0x13 + jne $ + + popad + popf + leave + add sp, 2 + jmp cs:OriginalInt13Handler + + pass15: + popad + popf + leave + add sp, 2 + jmp cs:OriginalInt15Handler + } +} + + +void Int13FilterEntry () +{ + __asm + { + leave + push 0x13 + jmp IntFilterEntry + } +} + + +static void Int15FilterEntry () +{ + __asm + { + pushf + cmp ax, 0xe820 // Get system memory map + je filter + + popf + leave + jmp cs:OriginalInt15Handler + + filter: + leave + push 0x15 + jmp IntFilterEntry + } +} + + +bool InstallInterruptFilters () +{ + +#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE + + // If the filters have already been installed, it usually indicates stack corruption + // and a consequent reentry of this routine without a system reset. + + uint32 currentInt13Handler; + CopyMemory (0, 0x13 * 4, ¤tInt13Handler, sizeof (currentInt13Handler)); + + if (currentInt13Handler == (uint32) Int13FilterEntry) + { + PrintError ("Memory corrupted"); + Print (TC_BOOT_STR_UPGRADE_BIOS); + + GetKeyboardChar(); + return true; + } + +#endif + + if (!CreateNewBiosMemoryMap()) + return false; + + __asm + { + cli + push es + + // Save original INT 13 handler + xor ax, ax + mov es, ax + + mov si, 0x13 * 4 + lea di, OriginalInt13Handler + + mov ax, es:[si] + mov [di], ax + mov ax, es:[si + 2] + mov [di + 2], ax + + // Install INT 13 filter + lea ax, Int13FilterEntry + mov es:[si], ax + mov es:[si + 2], cs + + // Save original INT 15 handler + mov si, 0x15 * 4 + lea di, OriginalInt15Handler + + mov ax, es:[si] + mov [di], ax + mov ax, es:[si + 2] + mov [di + 2], ax + + // Install INT 15 filter + lea ax, Int15FilterEntry + mov es:[si], ax + mov es:[si + 2], cs + + // If the BIOS does not support system memory map (INT15 0xe820), + // set amount of available memory to CS:0000 - 0:0000 + cmp BiosMemoryMapSize, 1 + jg mem_map_ok + mov ax, cs + shr ax, 10 - 4 // CS * 16 / 1024 + mov es:[0x413], ax // = KBytes available + mem_map_ok: + + pop es + sti + } + + return true; +} diff --git a/src/Boot/Windows/IntFilter.h b/src/Boot/Windows/IntFilter.h index af354802..1ef42512 100644 --- a/src/Boot/Windows/IntFilter.h +++ b/src/Boot/Windows/IntFilter.h @@ -1,20 +1,20 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_IntFilter -#define TC_HEADER_Boot_IntFilter - -#include "Platform.h" - -bool InstallInterruptFilters (); - -#endif TC_HEADER_Boot_IntFilter +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_IntFilter +#define TC_HEADER_Boot_IntFilter + +#include "Platform.h" + +bool InstallInterruptFilters (); + +#endif TC_HEADER_Boot_IntFilter diff --git a/src/Boot/Windows/Makefile b/src/Boot/Windows/Makefile index f9851051..65e668cb 100644 --- a/src/Boot/Windows/Makefile +++ b/src/Boot/Windows/Makefile @@ -1,202 +1,202 @@ -# -# Derived from source code of TrueCrypt 7.1a, which is -# Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed -# by the TrueCrypt License 3.0. -# -# Modifications and additions to the original source code (contained in this file) -# and all other portions of this file are Copyright (c) 2013-2016 IDRIX -# and are governed by the Apache License 2.0 the full text of which is -# contained in the file License.txt included in VeraCrypt binary and source -# code distribution packages. - -PROJ = BootLoader -.SILENT: - -!ifndef MSVC16_ROOT -!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5 -!endif - -ENVPATH = $(PATH) - -CC = $(MSVC16_ROOT)\bin\cl.exe -LD = $(MSVC16_ROOT)\bin\link.exe - -AFLAGS = /nologo /omf - -CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto" -CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1 -CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64 -CFLAGS = $(CFLAGS) /D malloc=malloc_NA - -LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH - -OBJDIR = Release - -!ifdef RESCUE_DISK -OBJDIR = Rescue -CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE -!endif - -!ifdef SINGLE_CIPHER -OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER) -CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER) -!endif - -!ifdef SINGLE_PRF -OBJDIR = $(OBJDIR)_$(SINGLE_PRF) -CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF) -!else -CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160 -!endif - -OUTDIR = $(OBJDIR) -TARGETEXT = com -TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com -CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG -LFLAGS = $(LFLAGS) /NOD /NOE /TINY -OBJS = $(OUTDIR)\BootCrt.obj -LIBS = slibce - -!if 1 -SRCDIR = .. -!else -SRCDIR = $(MAKEDIR) -!endif - -TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT) - -OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj -OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj -OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj -OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj -OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj -OBJS = $(OBJS) $(OUTDIR)\BootMain.obj -OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj -OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj -OBJS = $(OBJS) $(OUTDIR)\Platform.obj - -OBJS = $(OBJS) $(OUTDIR)\Crc.obj -OBJS = $(OBJS) $(OUTDIR)\Crypto.obj -OBJS = $(OBJS) $(OUTDIR)\Endian.obj -OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj -OBJS = $(OBJS) $(OUTDIR)\Volumes.obj -OBJS = $(OBJS) $(OUTDIR)\Xts.obj - -!if "$(SINGLE_PRF)" == "SHA2" -OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj -!else -OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj -!endif - -!if !DEFINED (SINGLE_CIPHER) -OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj -!else if "$(SINGLE_CIPHER)" == "AES" -OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj -OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj -OBJS = $(OBJS) $(OUTDIR)\Aestab.obj -!endif - -!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT" -OBJS = $(OBJS) $(OUTDIR)\Serpent.obj -!endif - -!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH" -OBJS = $(OBJS) $(OUTDIR)\Twofish.obj -!endif - - -all: env $(TARGETS) - -env: - set INCLUDE=. - set LIB=. - set LIBPATH=. - -clean: - -del /q /s $(OBJDIR) >NUL: - - -.asm{$(OUTDIR)}.obj: - cd $(OBJDIR) - $(AS) $(AFLAGS) /c "$(SRCDIR)\$<" - cd .. - -{..\..\Crypto}.asm{$(OUTDIR)}.obj: - cd $(OBJDIR) - echo $(NUL: - -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL: - cd .. - -$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj - cd $(OBJDIR) - $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,, - -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL: - cd .. - -$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS) - @echo Linking... - cd $(OBJDIR) - - echo >NUL: @<<$(PROJ).crf2 - -$(PROJ).$(TARGETEXT) -$(PROJ).map -$(MSVC16_ROOT)\lib\+ -$(LIBS) -; -<< - del $(PROJ).crf >NUL: 2>NUL: - for %F in ($(**F)) do @echo %F + >>$(PROJ).crf - type $(PROJ).crf2 >>$(PROJ).crf - - $(LD) $(LFLAGS) @$(PROJ).crf - del $(PROJ).crf $(PROJ).crf2 - -# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes) -!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT")) - upx $(PROJ).$(TARGETEXT) -!endif - gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz - -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL: - cd .. +# +# Derived from source code of TrueCrypt 7.1a, which is +# Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed +# by the TrueCrypt License 3.0. +# +# Modifications and additions to the original source code (contained in this file) +# and all other portions of this file are Copyright (c) 2013-2016 IDRIX +# and are governed by the Apache License 2.0 the full text of which is +# contained in the file License.txt included in VeraCrypt binary and source +# code distribution packages. + +PROJ = BootLoader +.SILENT: + +!ifndef MSVC16_ROOT +!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5 +!endif + +ENVPATH = $(PATH) + +CC = $(MSVC16_ROOT)\bin\cl.exe +LD = $(MSVC16_ROOT)\bin\link.exe + +AFLAGS = /nologo /omf + +CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto" +CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1 +CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64 +CFLAGS = $(CFLAGS) /D malloc=malloc_NA + +LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH + +OBJDIR = Release + +!ifdef RESCUE_DISK +OBJDIR = Rescue +CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE +!endif + +!ifdef SINGLE_CIPHER +OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER) +CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER) +!endif + +!ifdef SINGLE_PRF +OBJDIR = $(OBJDIR)_$(SINGLE_PRF) +CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF) +!else +CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160 +!endif + +OUTDIR = $(OBJDIR) +TARGETEXT = com +TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com +CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG +LFLAGS = $(LFLAGS) /NOD /NOE /TINY +OBJS = $(OUTDIR)\BootCrt.obj +LIBS = slibce + +!if 1 +SRCDIR = .. +!else +SRCDIR = $(MAKEDIR) +!endif + +TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT) + +OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj +OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj +OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj +OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj +OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj +OBJS = $(OBJS) $(OUTDIR)\BootMain.obj +OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj +OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj +OBJS = $(OBJS) $(OUTDIR)\Platform.obj + +OBJS = $(OBJS) $(OUTDIR)\Crc.obj +OBJS = $(OBJS) $(OUTDIR)\Crypto.obj +OBJS = $(OBJS) $(OUTDIR)\Endian.obj +OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj +OBJS = $(OBJS) $(OUTDIR)\Volumes.obj +OBJS = $(OBJS) $(OUTDIR)\Xts.obj + +!if "$(SINGLE_PRF)" == "SHA2" +OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj +!else +OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj +!endif + +!if !DEFINED (SINGLE_CIPHER) +OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj +!else if "$(SINGLE_CIPHER)" == "AES" +OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj +OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj +OBJS = $(OBJS) $(OUTDIR)\Aestab.obj +!endif + +!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT" +OBJS = $(OBJS) $(OUTDIR)\Serpent.obj +!endif + +!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH" +OBJS = $(OBJS) $(OUTDIR)\Twofish.obj +!endif + + +all: env $(TARGETS) + +env: + set INCLUDE=. + set LIB=. + set LIBPATH=. + +clean: + -del /q /s $(OBJDIR) >NUL: + + +.asm{$(OUTDIR)}.obj: + cd $(OBJDIR) + $(AS) $(AFLAGS) /c "$(SRCDIR)\$<" + cd .. + +{..\..\Crypto}.asm{$(OUTDIR)}.obj: + cd $(OBJDIR) + echo $(NUL: + -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL: + cd .. + +$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj + cd $(OBJDIR) + $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,, + -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL: + cd .. + +$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS) + @echo Linking... + cd $(OBJDIR) + + echo >NUL: @<<$(PROJ).crf2 + +$(PROJ).$(TARGETEXT) +$(PROJ).map +$(MSVC16_ROOT)\lib\+ +$(LIBS) +; +<< + del $(PROJ).crf >NUL: 2>NUL: + for %F in ($(**F)) do @echo %F + >>$(PROJ).crf + type $(PROJ).crf2 >>$(PROJ).crf + + $(LD) $(LFLAGS) @$(PROJ).crf + del $(PROJ).crf $(PROJ).crf2 + +# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes) +!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT")) + upx $(PROJ).$(TARGETEXT) +!endif + gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz + -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL: + cd .. diff --git a/src/Boot/Windows/Platform.cpp b/src/Boot/Windows/Platform.cpp index d9819cfa..316e71b3 100644 --- a/src/Boot/Windows/Platform.cpp +++ b/src/Boot/Windows/Platform.cpp @@ -1,230 +1,230 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#include "Platform.h" -#include "BootConsoleIo.h" - - -uint64 operator+ (const uint64 &a, const uint64 &b) -{ - int carry = 0; - uint64 r; - - r.LowPart = a.LowPart + b.LowPart; - __asm - { - jnc nocarry - mov carry, 1 - nocarry: - } - - r.HighPart = a.HighPart + b.HighPart + carry; - - return r; -} - -uint64 operator+ (const uint64 &a, uint32 b) -{ - uint64 b64; - b64.HighPart = 0; - b64.LowPart = b; - return a + b64; -} - -uint64 &operator+= (uint64 &a, const uint64 &b) -{ - return a = a + b; -} - -uint64 operator- (const uint64 &a, const uint64 &b) -{ - int carry = 0; - uint64 r; - - r.LowPart = a.LowPart - b.LowPart; - __asm - { - jnc nocarry - mov carry, 1 - nocarry: - } - - r.HighPart = a.HighPart - b.HighPart - carry; - - return r; -} - -uint64 operator- (const uint64 &a, uint32 b) -{ - uint64 b64; - b64.HighPart = 0; - b64.LowPart = b; - return a - b64; -} - -uint64 &operator-= (uint64 &a, const uint64 &b) -{ - return a = a - b; -} - -uint64 operator>> (const uint64 &a, int shiftCount) -{ - uint64 r = a; - - while (shiftCount--) - { - r.LowPart >>= 1; - - if ((byte) r.HighPart & 1) - r.LowPart |= 0x80000000UL; - - r.HighPart >>= 1; - } - - return r; -} - -uint64 operator<< (const uint64 &a, int shiftCount) -{ - uint64 r = a; - - while (shiftCount--) - r += r; - - return r; -} - -uint64 &operator++ (uint64 &a) -{ - uint64 b; - b.HighPart = 0; - b.LowPart = 1; - - return a += b; -} - -bool operator== (const uint64 &a, const uint64 &b) -{ - return a.HighPart == b.HighPart && a.LowPart == b.LowPart; -} - -bool operator> (const uint64 &a, const uint64 &b) -{ - return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart); -} - -bool operator< (const uint64 &a, const uint64 &b) -{ - return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart); -} - -bool operator>= (const uint64 &a, const uint64 &b) -{ - return a > b || a == b; -} - -bool operator<= (const uint64 &a, const uint64 &b) -{ - return a < b || a == b; -} - -bool TestInt64 () -{ - uint64 a, b, c; - a.HighPart = 0x00112233UL; - a.LowPart = 0xabcd1234UL; - - b.HighPart = 0x00ffeeddUL; - b.LowPart = 0xffffFFFFUL; - - a += b; - a -= b; - - ++a; - - b = b + (uint32) 1UL; - - c = (a - ((a + b) >> 32) - (uint32) 1UL); - if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL) - return false; - - c = c << 9; - return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL; -} - - -void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize) -{ - __asm - { - push es - mov si, ss:source - mov es, ss:destSegment - mov di, ss:destOffset - mov cx, ss:blockSize - cld - rep movsb - pop es - } -} - - -void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize) -{ - __asm - { - push ds - push es - mov ax, ds - mov es, ax - mov di, ss:destination - mov si, ss:sourceOffset - mov cx, ss:blockSize - mov ds, ss:sourceSegment - cld - rep movsb - pop es - pop ds - } -} - - -void EraseMemory (void *memory, int size) -{ - memset (memory, 0, size); -} - - -uint32 GetLinearAddress (uint16 segment, uint16 offset) -{ - return (uint32 (segment) << 4) + offset; -} - - -bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2) -{ - uint64 end1 = start1 + length1 - 1UL; - uint64 intersectEnd = (end1 <= end2) ? end1 : end2; - - uint64 intersectStart = (start1 >= start2) ? start1 : start2; - if (intersectStart > intersectEnd) - return false; - - return (intersectEnd + 1UL - intersectStart).LowPart != 0; -} - - -void ThrowFatalException (int line) -{ - PrintChar ('#'); Print (line); - while (1); -} +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Platform.h" +#include "BootConsoleIo.h" + + +uint64 operator+ (const uint64 &a, const uint64 &b) +{ + int carry = 0; + uint64 r; + + r.LowPart = a.LowPart + b.LowPart; + __asm + { + jnc nocarry + mov carry, 1 + nocarry: + } + + r.HighPart = a.HighPart + b.HighPart + carry; + + return r; +} + +uint64 operator+ (const uint64 &a, uint32 b) +{ + uint64 b64; + b64.HighPart = 0; + b64.LowPart = b; + return a + b64; +} + +uint64 &operator+= (uint64 &a, const uint64 &b) +{ + return a = a + b; +} + +uint64 operator- (const uint64 &a, const uint64 &b) +{ + int carry = 0; + uint64 r; + + r.LowPart = a.LowPart - b.LowPart; + __asm + { + jnc nocarry + mov carry, 1 + nocarry: + } + + r.HighPart = a.HighPart - b.HighPart - carry; + + return r; +} + +uint64 operator- (const uint64 &a, uint32 b) +{ + uint64 b64; + b64.HighPart = 0; + b64.LowPart = b; + return a - b64; +} + +uint64 &operator-= (uint64 &a, const uint64 &b) +{ + return a = a - b; +} + +uint64 operator>> (const uint64 &a, int shiftCount) +{ + uint64 r = a; + + while (shiftCount--) + { + r.LowPart >>= 1; + + if ((byte) r.HighPart & 1) + r.LowPart |= 0x80000000UL; + + r.HighPart >>= 1; + } + + return r; +} + +uint64 operator<< (const uint64 &a, int shiftCount) +{ + uint64 r = a; + + while (shiftCount--) + r += r; + + return r; +} + +uint64 &operator++ (uint64 &a) +{ + uint64 b; + b.HighPart = 0; + b.LowPart = 1; + + return a += b; +} + +bool operator== (const uint64 &a, const uint64 &b) +{ + return a.HighPart == b.HighPart && a.LowPart == b.LowPart; +} + +bool operator> (const uint64 &a, const uint64 &b) +{ + return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart); +} + +bool operator< (const uint64 &a, const uint64 &b) +{ + return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart); +} + +bool operator>= (const uint64 &a, const uint64 &b) +{ + return a > b || a == b; +} + +bool operator<= (const uint64 &a, const uint64 &b) +{ + return a < b || a == b; +} + +bool TestInt64 () +{ + uint64 a, b, c; + a.HighPart = 0x00112233UL; + a.LowPart = 0xabcd1234UL; + + b.HighPart = 0x00ffeeddUL; + b.LowPart = 0xffffFFFFUL; + + a += b; + a -= b; + + ++a; + + b = b + (uint32) 1UL; + + c = (a - ((a + b) >> 32) - (uint32) 1UL); + if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL) + return false; + + c = c << 9; + return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL; +} + + +void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize) +{ + __asm + { + push es + mov si, ss:source + mov es, ss:destSegment + mov di, ss:destOffset + mov cx, ss:blockSize + cld + rep movsb + pop es + } +} + + +void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize) +{ + __asm + { + push ds + push es + mov ax, ds + mov es, ax + mov di, ss:destination + mov si, ss:sourceOffset + mov cx, ss:blockSize + mov ds, ss:sourceSegment + cld + rep movsb + pop es + pop ds + } +} + + +void EraseMemory (void *memory, int size) +{ + memset (memory, 0, size); +} + + +uint32 GetLinearAddress (uint16 segment, uint16 offset) +{ + return (uint32 (segment) << 4) + offset; +} + + +bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2) +{ + uint64 end1 = start1 + length1 - 1UL; + uint64 intersectEnd = (end1 <= end2) ? end1 : end2; + + uint64 intersectStart = (start1 >= start2) ? start1 : start2; + if (intersectStart > intersectEnd) + return false; + + return (intersectEnd + 1UL - intersectStart).LowPart != 0; +} + + +void ThrowFatalException (int line) +{ + PrintChar ('#'); Print (line); + while (1); +} diff --git a/src/Boot/Windows/Platform.h b/src/Boot/Windows/Platform.h index 2fa532ce..879b1c39 100644 --- a/src/Boot/Windows/Platform.h +++ b/src/Boot/Windows/Platform.h @@ -1,116 +1,116 @@ -/* - Derived from source code of TrueCrypt 7.1a, which is - Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed - by the TrueCrypt License 3.0. - - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. -*/ - -#ifndef TC_HEADER_Boot_Platform -#define TC_HEADER_Boot_Platform - -#pragma warning (disable: 4018 4102 4704 4769) - -#include "TCdefs.h" -#include - -typedef char bool; -#define false 0 -#define true 1 - -#define nullptr 0 -#define NULL 0 - -typedef UINT64_STRUCT uint64; - -#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0])) - -#define TC_TO_STRING2(n) #n -#define TC_TO_STRING(n) TC_TO_STRING2(n) - - -#define TC_X86_CARRY_FLAG 0x1 - -#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B -#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C -#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D - -#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05) -#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D) -#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D) -#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15) - -#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05) -#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D) -#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D) -#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15) - - -#pragma pack(1) - -struct Registers -{ - uint16 Flags; - - union - { - uint32 EAX; - struct { uint16 AX; uint16 EAXH; }; - }; - - union - { - uint32 EBX; - struct { uint16 BX; uint16 EBXH; }; - }; - - union - { - uint32 ECX; - struct { uint16 CX; uint16 ECXH; }; - }; - - union - { - uint32 EDX; - struct { uint16 DX; uint16 EDXH; }; - }; - - uint16 DI; - uint16 SI; - uint16 DS; - uint16 ES; - uint16 SS; -}; - -#pragma pack() - - -uint64 operator+ (const uint64 &a, const uint64 &b); -uint64 operator+ (const uint64 &a, uint32 b); -uint64 &operator+= (uint64 &a, const uint64 &b); -uint64 operator- (const uint64 &a, const uint64 &b); -uint64 operator- (const uint64 &a, uint32 b); -uint64 &operator-= (uint64 &a, const uint64 &b); -uint64 operator>> (const uint64 &a, int shiftCount); -uint64 operator<< (const uint64 &a, int shiftCount); -uint64 &operator++ (uint64 &a); -bool operator== (const uint64 &a, const uint64 &b); -bool operator> (const uint64 &a, const uint64 &b); -bool operator< (const uint64 &a, const uint64 &b); -bool operator>= (const uint64 &a, const uint64 &b); -bool operator<= (const uint64 &a, const uint64 &b); - -void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize); -void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize); -extern "C" void EraseMemory (void *memory, int size); -uint32 GetLinearAddress (uint16 segment, uint16 offset); -bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2); -bool TestInt64 (); -extern "C" void ThrowFatalException (int line); - -#endif // TC_HEADER_Boot_Platform +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifndef TC_HEADER_Boot_Platform +#define TC_HEADER_Boot_Platform + +#pragma warning (disable: 4018 4102 4704 4769) + +#include "TCdefs.h" +#include + +typedef char bool; +#define false 0 +#define true 1 + +#define nullptr 0 +#define NULL 0 + +typedef UINT64_STRUCT uint64; + +#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0])) + +#define TC_TO_STRING2(n) #n +#define TC_TO_STRING(n) TC_TO_STRING2(n) + + +#define TC_X86_CARRY_FLAG 0x1 + +#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B +#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C +#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D + +#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05) +#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D) +#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D) +#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15) + +#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05) +#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D) +#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D) +#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15) + + +#pragma pack(1) + +struct Registers +{ + uint16 Flags; + + union + { + uint32 EAX; + struct { uint16 AX; uint16 EAXH; }; + }; + + union + { + uint32 EBX; + struct { uint16 BX; uint16 EBXH; }; + }; + + union + { + uint32 ECX; + struct { uint16 CX; uint16 ECXH; }; + }; + + union + { + uint32 EDX; + struct { uint16 DX; uint16 EDXH; }; + }; + + uint16 DI; + uint16 SI; + uint16 DS; + uint16 ES; + uint16 SS; +}; + +#pragma pack() + + +uint64 operator+ (const uint64 &a, const uint64 &b); +uint64 operator+ (const uint64 &a, uint32 b); +uint64 &operator+= (uint64 &a, const uint64 &b); +uint64 operator- (const uint64 &a, const uint64 &b); +uint64 operator- (const uint64 &a, uint32 b); +uint64 &operator-= (uint64 &a, const uint64 &b); +uint64 operator>> (const uint64 &a, int shiftCount); +uint64 operator<< (const uint64 &a, int shiftCount); +uint64 &operator++ (uint64 &a); +bool operator== (const uint64 &a, const uint64 &b); +bool operator> (const uint64 &a, const uint64 &b); +bool operator< (const uint64 &a, const uint64 &b); +bool operator>= (const uint64 &a, const uint64 &b); +bool operator<= (const uint64 &a, const uint64 &b); + +void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize); +void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize); +extern "C" void EraseMemory (void *memory, int size); +uint32 GetLinearAddress (uint16 segment, uint16 offset); +bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2); +bool TestInt64 (); +extern "C" void ThrowFatalException (int line); + +#endif // TC_HEADER_Boot_Platform -- cgit v1.2.3