|
|
1.1 root 1: /* 1.1.1.12! root 2: Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. 1.1 root 3: 1.1.1.12! root 4: Governed by the TrueCrypt License 3.0 the full text of which is contained in 1.1.1.11 root 5: the file License.txt included in TrueCrypt binary and source code distribution 6: packages. 1.1 root 7: */ 8: 9: #include "Tcdefs.h" 10: #include "Platform/Finally.h" 11: #include "Platform/ForEach.h" 12: #include <Setupapi.h> 13: #include <devguid.h> 14: #include <io.h> 15: #include <shlobj.h> 16: #include <atlbase.h> 17: #include "BootEncryption.h" 18: #include "Boot/Windows/BootCommon.h" 19: #include "Common/Resource.h" 20: #include "Crc.h" 21: #include "Crypto.h" 22: #include "Dlgcode.h" 23: #include "Endian.h" 1.1.1.5 root 24: #include "Language.h" 1.1 root 25: #include "Random.h" 26: #include "Registry.h" 27: #include "Volumes.h" 28: 29: #ifdef VOLFORMAT 30: #include "Format/FormatCom.h" 31: #elif defined (TCMOUNT) 32: #include "Mount/MainCom.h" 33: #endif 34: 35: namespace TrueCrypt 36: { 37: #if !defined (SETUP) 38: 39: class Elevator 40: { 41: public: 1.1.1.6 root 42: 43: static void AddReference () 44: { 45: ++ReferenceCount; 46: } 47: 48: 1.1 root 49: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) 50: { 51: Elevate(); 52: 53: CComBSTR inputBstr; 54: if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK) 55: throw ParameterIncorrect (SRC_POS); 56: 57: CComBSTR outputBstr; 58: if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK) 59: throw ParameterIncorrect (SRC_POS); 60: 61: DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr); 1.1.1.5 root 62: 63: if (output) 64: memcpy (output, *(void **) &outputBstr, outputSize); 65: 1.1 root 66: if (result != ERROR_SUCCESS) 67: { 68: SetLastError (result); 69: throw SystemException(); 70: } 71: } 72: 1.1.1.10 root 73: static void CopyFile (const string &sourceFile, const string &destinationFile) 74: { 75: Elevate(); 76: 77: DWORD result = ElevatedComInstance->CopyFile (CComBSTR (sourceFile.c_str()), CComBSTR (destinationFile.c_str())); 78: 79: if (result != ERROR_SUCCESS) 80: { 81: SetLastError (result); 82: throw SystemException(); 83: } 84: } 85: 86: static void DeleteFile (const string &file) 87: { 88: Elevate(); 89: 90: DWORD result = ElevatedComInstance->DeleteFile (CComBSTR (file.c_str())); 91: 92: if (result != ERROR_SUCCESS) 93: { 94: SetLastError (result); 95: throw SystemException(); 96: } 97: } 98: 1.1 root 99: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) 100: { 101: Elevate(); 102: 103: CComBSTR bufferBstr; 104: if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK) 105: throw ParameterIncorrect (SRC_POS); 106: DWORD result = ElevatedComInstance->ReadWriteFile (write, device, CComBSTR (filePath.c_str()), &bufferBstr, offset, size, sizeDone); 107: 108: if (result != ERROR_SUCCESS) 109: { 110: SetLastError (result); 111: throw SystemException(); 112: } 113: 114: if (!write) 115: memcpy (buffer, (BYTE *) bufferBstr.m_str, size); 116: } 117: 1.1.1.6 root 118: static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) 1.1.1.5 root 119: { 120: Elevate(); 121: 1.1.1.6 root 122: return ElevatedComInstance->IsPagingFileActive (checkNonWindowsPartitionsOnly); 1.1.1.5 root 123: } 124: 125: static void WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value) 1.1 root 126: { 127: Elevate(); 128: 1.1.1.5 root 129: DWORD result = ElevatedComInstance->WriteLocalMachineRegistryDwordValue (CComBSTR (keyPath), CComBSTR (valueName), value); 130: 131: if (result != ERROR_SUCCESS) 132: { 133: SetLastError (result); 134: throw SystemException(); 135: } 136: } 137: 1.1.1.12! root 138: static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType) 1.1.1.5 root 139: { 140: Elevate(); 141: 1.1.1.12! root 142: DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE, filterType); 1.1 root 143: if (result != ERROR_SUCCESS) 144: { 145: SetLastError (result); 146: throw SystemException(); 147: } 148: } 149: 1.1.1.10 root 150: static void RegisterSystemFavoritesService (BOOL registerService) 151: { 152: Elevate(); 153: 154: DWORD result = ElevatedComInstance->RegisterSystemFavoritesService (registerService); 155: if (result != ERROR_SUCCESS) 156: { 157: SetLastError (result); 158: throw SystemException(); 159: } 160: } 1.1.1.6 root 161: 1.1 root 162: static void Release () 163: { 1.1.1.6 root 164: if (--ReferenceCount == 0 && ElevatedComInstance) 1.1 root 165: { 166: ElevatedComInstance->Release(); 167: ElevatedComInstance = nullptr; 168: CoUninitialize (); 169: } 170: } 171: 172: static void SetDriverServiceStartType (DWORD startType) 173: { 174: Elevate(); 175: 176: DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType); 177: if (result != ERROR_SUCCESS) 178: { 179: SetLastError (result); 180: throw SystemException(); 181: } 182: } 183: 184: protected: 185: static void Elevate () 186: { 187: if (IsAdmin()) 188: { 189: SetLastError (ERROR_ACCESS_DENIED); 190: throw SystemException(); 191: } 192: 1.1.1.5 root 193: if (!ElevatedComInstance || ElevatedComInstanceThreadId != GetCurrentThreadId()) 1.1 root 194: { 195: CoInitialize (NULL); 196: ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg); 1.1.1.5 root 197: ElevatedComInstanceThreadId = GetCurrentThreadId(); 1.1 root 198: } 199: } 200: 201: #if defined (TCMOUNT) 202: static ITrueCryptMainCom *ElevatedComInstance; 203: #elif defined (VOLFORMAT) 204: static ITrueCryptFormatCom *ElevatedComInstance; 205: #endif 1.1.1.5 root 206: static DWORD ElevatedComInstanceThreadId; 1.1.1.6 root 207: static int ReferenceCount; 1.1 root 208: }; 209: 210: #if defined (TCMOUNT) 211: ITrueCryptMainCom *Elevator::ElevatedComInstance; 212: #elif defined (VOLFORMAT) 213: ITrueCryptFormatCom *Elevator::ElevatedComInstance; 214: #endif 1.1.1.5 root 215: DWORD Elevator::ElevatedComInstanceThreadId; 1.1.1.6 root 216: int Elevator::ReferenceCount = 0; 1.1 root 217: 218: #else // SETUP 219: 220: class Elevator 221: { 222: public: 1.1.1.6 root 223: static void AddReference () { } 1.1 root 224: static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); } 225: static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); } 1.1.1.12! root 226: static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType) { throw ParameterIncorrect (SRC_POS); } 1.1 root 227: static void Release () { } 228: static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); } 229: }; 230: 231: #endif // SETUP 232: 233: 234: File::File (string path, bool readOnly, bool create) : Elevated (false), FileOpen (false) 235: { 236: Handle = CreateFile (path.c_str(), 1.1.1.6 root 237: readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, 1.1 root 238: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING, 239: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL); 240: 241: try 242: { 243: throw_sys_if (Handle == INVALID_HANDLE_VALUE); 244: } 245: catch (SystemException &) 246: { 247: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) 248: Elevated = true; 249: else 250: throw; 251: } 252: 253: FileOpen = true; 254: FilePointerPosition = 0; 255: IsDevice = false; 256: Path = path; 257: } 258: 259: void File::Close () 260: { 261: if (FileOpen) 262: { 263: if (!Elevated) 264: CloseHandle (Handle); 265: 266: FileOpen = false; 267: } 268: } 269: 270: DWORD File::Read (byte *buffer, DWORD size) 271: { 272: DWORD bytesRead; 273: 274: if (Elevated) 275: { 276: DWORD bytesRead; 277: 278: Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead); 279: FilePointerPosition += bytesRead; 280: return bytesRead; 281: } 282: 283: throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL)); 284: return bytesRead; 285: } 286: 287: void File::SeekAt (int64 position) 288: { 1.1.1.6 root 289: FilePointerPosition = position; 290: 291: if (!Elevated) 1.1 root 292: { 293: LARGE_INTEGER pos; 294: pos.QuadPart = position; 295: throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN)); 296: } 297: } 298: 299: void File::Write (byte *buffer, DWORD size) 300: { 301: DWORD bytesWritten; 1.1.1.6 root 302: 303: try 1.1 root 304: { 1.1.1.6 root 305: if (Elevated) 306: { 307: Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten); 308: FilePointerPosition += bytesWritten; 309: throw_sys_if (bytesWritten != size); 310: } 311: else 312: { 313: throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size); 314: } 1.1 root 315: } 1.1.1.6 root 316: catch (SystemException &e) 1.1 root 317: { 1.1.1.10 root 318: if (!IsDevice || e.ErrorCode != ERROR_WRITE_PROTECT) 1.1.1.6 root 319: throw; 320: 321: BootEncryption bootEnc (NULL); 322: 1.1.1.12! root 323: while (size >= TC_SECTOR_SIZE_BIOS) 1.1.1.6 root 324: { 325: bootEnc.WriteBootDriveSector (FilePointerPosition, buffer); 326: 1.1.1.12! root 327: FilePointerPosition += TC_SECTOR_SIZE_BIOS; ! 328: buffer += TC_SECTOR_SIZE_BIOS; ! 329: size -= TC_SECTOR_SIZE_BIOS; 1.1.1.6 root 330: } 1.1 root 331: } 332: } 333: 334: void Show (HWND parent, const string &str) 335: { 336: MessageBox (parent, str.c_str(), NULL, 0); 337: } 338: 339: 340: Device::Device (string path, bool readOnly) 341: { 342: FileOpen = false; 343: Elevated = false; 344: 345: Handle = CreateFile ((string ("\\\\.\\") + path).c_str(), 1.1.1.6 root 346: readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, 1.1 root 347: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 348: FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL); 349: 350: try 351: { 352: throw_sys_if (Handle == INVALID_HANDLE_VALUE); 353: } 354: catch (SystemException &) 355: { 356: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) 357: Elevated = true; 358: else 359: throw; 360: } 361: 362: FileOpen = true; 363: FilePointerPosition = 0; 364: IsDevice = true; 365: Path = path; 366: } 367: 368: 1.1.1.6 root 369: BootEncryption::BootEncryption (HWND parent) 370: : DriveConfigValid (false), 371: ParentWindow (parent), 372: RealSystemDriveSizeValid (false), 373: RescueIsoImage (nullptr), 374: RescueVolumeHeaderValid (false), 375: SelectedEncryptionAlgorithmId (0), 376: VolumeHeaderValid (false) 377: { 378: Elevator::AddReference(); 379: } 380: 381: 1.1 root 382: BootEncryption::~BootEncryption () 383: { 384: if (RescueIsoImage) 1.1.1.12! root 385: delete[] RescueIsoImage; 1.1 root 386: 387: Elevator::Release(); 388: } 389: 390: 391: void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) 392: { 393: try 394: { 395: DWORD bytesReturned; 396: throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL)); 397: } 398: catch (SystemException &) 399: { 400: if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported()) 401: Elevator::CallDriver (ioctl, input, inputSize, output, outputSize); 402: else 403: throw; 404: } 405: } 406: 407: 1.1.1.5 root 408: // Finds the first partition physically located behind the active one and returns its properties 409: Partition BootEncryption::GetPartitionForHiddenOS () 410: { 411: Partition candidatePartition; 412: 413: memset (&candidatePartition, 0, sizeof(candidatePartition)); 414: 415: // The user may have modified/added/deleted partitions since the time the partition table was last scanned 416: InvalidateCachedSysDriveProperties(); 417: 418: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 419: bool activePartitionFound = false; 420: bool candidateForHiddenOSFound = false; 421: 422: if (config.SystemPartition.IsGPT) 423: throw ParameterIncorrect (SRC_POS); // It is assumed that CheckRequirements() had been called 424: 425: // Find the first active partition on the system drive 426: foreach (const Partition &partition, config.Partitions) 427: { 428: if (partition.Info.BootIndicator) 429: { 430: if (partition.Info.PartitionNumber != config.SystemPartition.Number) 431: { 1.1.1.10 root 432: // If there is an extra boot partition, the system partition must be located right behind it 433: if (IsOSAtLeast (WIN_7) && config.ExtraBootPartitionPresent) 434: { 435: int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart; 436: Partition bootPartition = partition; 437: Partition partitionBehindBoot; 438: 439: foreach (const Partition &partition, config.Partitions) 440: { 441: if (partition.Info.StartingOffset.QuadPart > bootPartition.Info.StartingOffset.QuadPart 442: && partition.Info.StartingOffset.QuadPart < minOffsetFound) 443: { 444: minOffsetFound = partition.Info.StartingOffset.QuadPart; 445: partitionBehindBoot = partition; 446: } 447: } 448: 449: if (minOffsetFound != config.DrivePartition.Info.PartitionLength.QuadPart 450: && partitionBehindBoot.Number == config.SystemPartition.Number) 451: { 452: activePartitionFound = true; 453: break; 454: } 455: } 456: 1.1.1.5 root 457: throw ErrorException (wstring (GetString ("SYSTEM_PARTITION_NOT_ACTIVE")) 458: + GetRemarksOnHiddenOS()); 459: } 460: 461: activePartitionFound = true; 462: break; 463: } 464: } 465: 466: /* WARNING: Note that the partition number at the end of a device path (\Device\HarddiskY\PartitionX) must 467: NOT be used to find the first partition physically located behind the active one. The reason is that the 468: user may have deleted and created partitions during this session and e.g. the second partition could have 469: a higer number than the third one. */ 470: 471: 472: // Find the first partition physically located behind the active partition 473: if (activePartitionFound) 474: { 475: int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart; 476: 477: foreach (const Partition &partition, config.Partitions) 478: { 479: if (partition.Info.StartingOffset.QuadPart > config.SystemPartition.Info.StartingOffset.QuadPart 480: && partition.Info.StartingOffset.QuadPart < minOffsetFound) 481: { 482: minOffsetFound = partition.Info.StartingOffset.QuadPart; 483: 484: candidatePartition = partition; 485: 486: candidateForHiddenOSFound = true; 487: } 488: } 489: 490: if (!candidateForHiddenOSFound) 491: { 492: throw ErrorException (wstring (GetString ("NO_PARTITION_FOLLOWS_BOOT_PARTITION")) 493: + GetRemarksOnHiddenOS()); 494: } 495: 1.1.1.12! root 496: if (config.SystemPartition.Info.PartitionLength.QuadPart > TC_MAX_FAT_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) 1.1.1.5 root 497: { 498: if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS) 499: { 500: throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS_NTFS")) 501: + GetRemarksOnHiddenOS()); 502: } 503: } 504: else if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT) 505: { 506: throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS")) 507: + GetRemarksOnHiddenOS()); 508: } 509: } 510: else 511: { 512: // No active partition on the system drive 1.1.1.10 root 513: throw ErrorException ("SYSTEM_PARTITION_NOT_ACTIVE"); 1.1.1.5 root 514: } 515: 1.1.1.6 root 516: HiddenOSCandidatePartition = candidatePartition; 1.1.1.5 root 517: return candidatePartition; 518: } 519: 520: 1.1 root 521: DWORD BootEncryption::GetDriverServiceStartType () 522: { 523: DWORD startType; 524: throw_sys_if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", &startType)); 525: return startType; 526: } 527: 528: 1.1.1.5 root 529: wstring BootEncryption::GetRemarksOnHiddenOS () 530: { 531: return (wstring (L"\n\n") 532: + GetString ("TWO_SYSTEMS_IN_ONE_PARTITION_REMARK") 533: + L"\n\n" 534: + GetString ("FOR_MORE_INFO_ON_PARTITIONS")); 535: } 536: 537: 1.1 root 538: void BootEncryption::SetDriverServiceStartType (DWORD startType) 539: { 540: if (!IsAdmin() && IsUacSupported()) 541: { 542: Elevator::SetDriverServiceStartType (startType); 543: return; 544: } 545: 546: BOOL startOnBoot = (startType == SERVICE_BOOT_START); 547: 548: SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); 549: throw_sys_if (!serviceManager); 550: 551: finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); }); 552: 553: SC_HANDLE service = OpenService (serviceManager, "truecrypt", SERVICE_CHANGE_CONFIG); 554: throw_sys_if (!service); 555: 556: finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); }); 557: 1.1.1.5 root 558: // Windows versions preceding Vista can be installed on FAT filesystem which does not 559: // support long filenames during boot. Convert the driver path to short form if required. 560: string driverPath; 1.1.1.8 root 561: if (startOnBoot && !IsOSAtLeast (WIN_VISTA)) 1.1.1.5 root 562: { 563: char pathBuf[MAX_PATH]; 564: char filesystem[128]; 565: 566: string path (GetWindowsDirectory()); 567: path += "\\drivers\\truecrypt.sys"; 568: 569: if (GetVolumePathName (path.c_str(), pathBuf, sizeof (pathBuf)) 570: && GetVolumeInformation (pathBuf, NULL, 0, NULL, NULL, NULL, filesystem, sizeof(filesystem)) 571: && memcmp (filesystem, "FAT", 3) == 0) 572: { 573: throw_sys_if (GetShortPathName (path.c_str(), pathBuf, sizeof (pathBuf)) == 0); 574: 575: // Convert absolute path to relative to the Windows directory 576: driverPath = pathBuf; 577: driverPath = driverPath.substr (driverPath.rfind ("\\", driverPath.rfind ("\\", driverPath.rfind ("\\") - 1) - 1) + 1); 578: } 579: } 580: 1.1 root 581: throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, 1.1.1.5 root 582: startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL, 583: driverPath.empty() ? NULL : driverPath.c_str(), 1.1 root 584: startOnBoot ? "Filter" : NULL, 585: NULL, NULL, NULL, NULL, NULL)); 586: 587: // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER 588: throw_sys_if (!WriteLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", startType)); 589: } 590: 591: 592: void BootEncryption::ProbeRealSystemDriveSize () 593: { 594: if (RealSystemDriveSizeValid) 595: return; 596: 597: GetSystemDriveConfiguration(); 598: 599: ProbeRealDriveSizeRequest request; 600: _snwprintf (request.DeviceName, array_capacity (request.DeviceName), L"%hs", DriveConfig.DrivePartition.DevicePath.c_str()); 601: 602: CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request)); 603: DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize; 604: 1.1.1.5 root 605: RealSystemDriveSizeValid = true; 1.1.1.3 root 606: 607: if (request.TimeOut) 608: throw TimeOut (SRC_POS); 1.1 root 609: } 610: 611: 1.1.1.5 root 612: void BootEncryption::InvalidateCachedSysDriveProperties () 613: { 614: DriveConfigValid = false; 615: RealSystemDriveSizeValid = false; 616: } 617: 618: 1.1 root 619: PartitionList BootEncryption::GetDrivePartitions (int driveNumber) 620: { 621: PartitionList partList; 622: 623: for (int partNumber = 0; partNumber < 64; ++partNumber) 624: { 625: stringstream partPath; 626: partPath << "\\Device\\Harddisk" << driveNumber << "\\Partition" << partNumber; 627: 628: DISK_PARTITION_INFO_STRUCT diskPartInfo; 629: _snwprintf (diskPartInfo.deviceName, array_capacity (diskPartInfo.deviceName), L"%hs", partPath.str().c_str()); 630: 631: try 632: { 633: CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo)); 634: } 635: catch (...) 636: { 637: continue; 638: } 639: 640: Partition part; 641: part.DevicePath = partPath.str(); 642: part.Number = partNumber; 643: part.Info = diskPartInfo.partInfo; 644: part.IsGPT = diskPartInfo.IsGPT; 645: 646: // Mount point 647: wstringstream ws; 648: ws << partPath.str().c_str(); 649: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str()); 650: 651: if (driveNumber >= 0) 652: { 653: part.MountPoint += (char) (driveNumber + 'A'); 654: part.MountPoint += ":"; 655: } 1.1.1.8 root 656: 657: // Volume ID 658: wchar_t volumePath[TC_MAX_PATH]; 659: if (ResolveSymbolicLink ((wchar_t *) ws.str().c_str(), volumePath)) 660: { 661: wchar_t volumeName[TC_MAX_PATH]; 662: HANDLE fh = FindFirstVolumeW (volumeName, array_capacity (volumeName)); 663: if (fh != INVALID_HANDLE_VALUE) 664: { 665: do 666: { 667: wstring volumeNameStr = volumeName; 668: wchar_t devicePath[TC_MAX_PATH]; 669: 670: if (QueryDosDeviceW (volumeNameStr.substr (4, volumeNameStr.size() - 1 - 4).c_str(), devicePath, array_capacity (devicePath)) != 0 671: && wcscmp (volumePath, devicePath) == 0) 672: { 673: part.VolumeNameId = volumeName; 674: break; 675: } 676: 677: } while (FindNextVolumeW (fh, volumeName, array_capacity (volumeName))); 678: 679: FindVolumeClose (fh); 680: } 681: } 682: 1.1 root 683: partList.push_back (part); 684: } 685: 686: return partList; 687: } 688: 689: 690: DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber) 691: { 692: stringstream devName; 693: devName << "\\Device\\Harddisk" << driveNumber << "\\Partition0"; 694: 695: DISK_GEOMETRY geometry; 696: throw_sys_if (!::GetDriveGeometry ((char *) devName.str().c_str(), &geometry)); 697: return geometry; 698: } 699: 700: 701: string BootEncryption::GetWindowsDirectory () 702: { 703: char buf[MAX_PATH]; 1.1.1.5 root 704: throw_sys_if (GetSystemDirectory (buf, sizeof (buf)) == 0); 705: 706: return string (buf); 1.1 root 707: } 1.1.1.6 root 708: 709: 710: string BootEncryption::GetTempPath () 711: { 712: char tempPath[MAX_PATH]; 713: DWORD tempLen = ::GetTempPath (sizeof (tempPath), tempPath); 714: if (tempLen == 0 || tempLen > sizeof (tempPath)) 715: throw ParameterIncorrect (SRC_POS); 716: 717: return string (tempPath); 718: } 719: 1.1 root 720: 721: uint16 BootEncryption::GetInstalledBootLoaderVersion () 722: { 723: uint16 version; 724: CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version)); 725: return version; 726: } 727: 728: 1.1.1.3 root 729: // Note that this does not require admin rights (it just requires the driver to be running) 730: bool BootEncryption::IsBootLoaderOnDrive (char *devicePath) 731: { 732: try 733: { 734: OPEN_TEST_STRUCT openTestStruct; 1.1.1.8 root 735: memset (&openTestStruct, 0, sizeof (openTestStruct)); 1.1.1.3 root 736: DWORD dwResult; 737: 738: strcpy ((char *) &openTestStruct.wszFileName[0], devicePath); 739: ToUNICODE ((char *) &openTestStruct.wszFileName[0]); 740: 741: openTestStruct.bDetectTCBootLoader = TRUE; 742: 743: return (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, 744: &openTestStruct, sizeof (OPEN_TEST_STRUCT), 1.1.1.8 root 745: &openTestStruct, sizeof (OPEN_TEST_STRUCT), 746: &dwResult, NULL) && openTestStruct.TCBootLoaderDetected); 1.1.1.3 root 747: } 748: catch (...) 749: { 750: return false; 751: } 752: } 753: 754: 1.1 root 755: BootEncryptionStatus BootEncryption::GetStatus () 756: { 757: /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */ 758: 759: BootEncryptionStatus status; 760: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status)); 761: return status; 762: } 763: 764: 765: void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties) 766: { 767: if (properties == NULL) 768: throw ParameterIncorrect (SRC_POS); 769: 770: CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties)); 771: } 772: 773: 1.1.1.5 root 774: bool BootEncryption::IsHiddenSystemRunning () 775: { 776: int hiddenSystemStatus; 777: 778: CallDriver (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING, nullptr, 0, &hiddenSystemStatus, sizeof (hiddenSystemStatus)); 779: return hiddenSystemStatus != 0; 780: } 781: 782: 1.1.1.2 root 783: bool BootEncryption::SystemDriveContainsPartitionType (byte type) 784: { 785: Device device (GetSystemDriveConfiguration().DevicePath, true); 786: 1.1.1.12! root 787: byte mbrBuf[TC_SECTOR_SIZE_BIOS]; 1.1.1.2 root 788: device.SeekAt (0); 789: device.Read (mbrBuf, sizeof (mbrBuf)); 790: 791: MBR *mbr = reinterpret_cast <MBR *> (mbrBuf); 792: if (mbr->Signature != 0xaa55) 793: throw ParameterIncorrect (SRC_POS); 794: 795: for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i) 796: { 797: if (mbr->Partitions[i].Type == type) 798: return true; 799: } 800: 801: return false; 802: } 803: 804: 805: bool BootEncryption::SystemDriveContainsExtendedPartition () 806: { 807: return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED); 808: } 809: 810: 811: bool BootEncryption::SystemDriveIsDynamic () 812: { 1.1.1.5 root 813: GetSystemDriveConfigurationRequest request; 814: _snwprintf (request.DevicePath, array_capacity (request.DevicePath), L"%hs", GetSystemDriveConfiguration().DeviceKernelPath.c_str()); 815: 816: CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request)); 817: return request.DriveIsDynamic ? true : false; 1.1.1.2 root 818: } 819: 820: 1.1 root 821: SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration () 822: { 823: if (DriveConfigValid) 824: return DriveConfig; 825: 826: SystemDriveConfiguration config; 827: 828: string winDir = GetWindowsDirectory(); 829: 830: // Scan all drives 831: for (int driveNumber = 0; driveNumber < 32; ++driveNumber) 832: { 833: bool windowsFound = false; 1.1.1.10 root 834: bool activePartitionFound = false; 835: config.ExtraBootPartitionPresent = false; 1.1 root 836: config.SystemLoaderPresent = false; 837: 838: PartitionList partitions = GetDrivePartitions (driveNumber); 839: foreach (const Partition &part, partitions) 840: { 1.1.1.5 root 841: if (!part.MountPoint.empty() 842: && (_access ((part.MountPoint + "\\bootmgr").c_str(), 0) == 0 || _access ((part.MountPoint + "\\ntldr").c_str(), 0) == 0)) 843: { 1.1 root 844: config.SystemLoaderPresent = true; 1.1.1.5 root 845: } 1.1.1.8 root 846: else if (!part.VolumeNameId.empty() 847: && (_waccess ((part.VolumeNameId + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.VolumeNameId + L"\\ntldr").c_str(), 0) == 0)) 848: { 849: config.SystemLoaderPresent = true; 850: } 1.1 root 851: 1.1.1.6 root 852: if (!windowsFound && !part.MountPoint.empty() && ToUpperCase (winDir).find (ToUpperCase (part.MountPoint)) == 0) 1.1 root 853: { 854: config.SystemPartition = part; 855: windowsFound = true; 856: } 1.1.1.10 root 857: 858: if (!activePartitionFound && part.Info.BootIndicator) 859: { 860: activePartitionFound = true; 861: 862: if (part.Info.PartitionLength.QuadPart > 0 && part.Info.PartitionLength.QuadPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE) 863: config.ExtraBootPartitionPresent = true; 864: } 1.1 root 865: } 866: 867: if (windowsFound) 868: { 869: config.DriveNumber = driveNumber; 870: 871: stringstream ss; 872: ss << "PhysicalDrive" << driveNumber; 873: config.DevicePath = ss.str(); 874: 1.1.1.5 root 875: stringstream kernelPath; 876: kernelPath << "\\Device\\Harddisk" << driveNumber << "\\Partition0"; 877: config.DeviceKernelPath = kernelPath.str(); 878: 1.1 root 879: config.DrivePartition = partitions.front(); 880: partitions.pop_front(); 881: config.Partitions = partitions; 882: 883: config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull; 884: config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart; 885: 886: foreach (const Partition &part, config.Partitions) 887: { 888: if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace) 889: config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart; 890: 891: config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart; 892: } 893: 894: DriveConfig = config; 1.1.1.5 root 895: DriveConfigValid = true; 1.1 root 896: return DriveConfig; 897: } 898: } 899: 900: throw ParameterIncorrect (SRC_POS); 901: } 902: 903: 904: bool BootEncryption::SystemPartitionCoversWholeDrive () 905: { 906: SystemDriveConfiguration config = GetSystemDriveConfiguration(); 907: 1.1.1.10 root 908: if (IsOSAtLeast (WIN_7) 909: && config.Partitions.size() == 2 910: && config.ExtraBootPartitionPresent 911: && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 164 * BYTES_PER_MB) 912: { 913: return true; 914: } 915: 1.1 root 916: return config.Partitions.size() == 1 1.1.1.3 root 917: && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * BYTES_PER_MB; 1.1 root 918: } 919: 920: 1.1.1.3 root 921: uint32 BootEncryption::GetChecksum (byte *data, size_t size) 1.1 root 922: { 1.1.1.3 root 923: uint32 sum = 0; 924: 925: while (size-- > 0) 926: { 927: sum += *data++; 928: sum = _rotl (sum, 1); 929: } 930: 931: return sum; 932: } 933: 934: 1.1.1.6 root 935: void BootEncryption::CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation) 1.1.1.3 root 936: { 1.1.1.5 root 937: if (bufferSize < TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE) 1.1.1.3 root 938: throw ParameterIncorrect (SRC_POS); 939: 940: ZeroMemory (buffer, bufferSize); 941: 942: int ea = 0; 943: if (GetStatus().DriveMounted) 944: { 945: try 946: { 947: GetBootEncryptionAlgorithmNameRequest request; 948: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request)); 949: 950: if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0) 951: ea = AES; 952: else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0) 953: ea = SERPENT; 954: else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0) 955: ea = TWOFISH; 956: } 957: catch (...) 958: { 959: try 960: { 961: VOLUME_PROPERTIES_STRUCT properties; 962: GetVolumeProperties (&properties); 963: ea = properties.ea; 964: } 965: catch (...) { } 966: } 967: } 968: else 969: { 970: if (SelectedEncryptionAlgorithmId == 0) 971: throw ParameterIncorrect (SRC_POS); 972: 973: ea = SelectedEncryptionAlgorithmId; 974: } 975: 1.1.1.5 root 976: int bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR; 977: int bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER; 1.1.1.3 root 978: 979: switch (ea) 980: { 981: case AES: 1.1.1.5 root 982: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES; 983: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES; 1.1.1.3 root 984: break; 985: 986: case SERPENT: 1.1.1.5 root 987: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT; 988: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT; 1.1.1.3 root 989: break; 990: 991: case TWOFISH: 1.1.1.5 root 992: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH; 993: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH; 1.1.1.3 root 994: break; 995: } 996: 997: // Boot sector 1.1 root 998: DWORD size; 1.1.1.3 root 999: byte *bootSecResourceImg = MapResource ("BIN", bootSectorId, &size); 1.1.1.12! root 1000: if (!bootSecResourceImg || size != TC_SECTOR_SIZE_BIOS) 1.1.1.3 root 1001: throw ParameterIncorrect (SRC_POS); 1002: 1003: memcpy (buffer, bootSecResourceImg, size); 1.1 root 1004: 1.1.1.6 root 1005: *(uint16 *) (buffer + TC_BOOT_SECTOR_VERSION_OFFSET) = BE16 (VERSION_NUM); 1006: 1.1.1.8 root 1007: if (IsOSAtLeast (WIN_VISTA)) 1.1.1.3 root 1008: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER; 1009: 1.1.1.12! root 1010: if (rescueDisk && (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION)) ! 1011: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION; ! 1012: 1.1.1.6 root 1013: // Checksum of the backup header of the outer volume for the hidden system 1014: if (hiddenOSCreation) 1015: { 1016: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.12! root 1017: byte headerSector[TC_SECTOR_SIZE_BIOS]; 1.1.1.6 root 1018: 1019: device.SeekAt (HiddenOSCandidatePartition.Info.StartingOffset.QuadPart + HiddenOSCandidatePartition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_GROUP_SIZE + TC_VOLUME_HEADER_EFFECTIVE_SIZE); 1020: device.Read (headerSector, sizeof (headerSector)); 1021: 1.1.1.8 root 1022: *(uint32 *) (buffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET) = GetCrc32 (headerSector, sizeof (headerSector)); 1.1.1.6 root 1023: } 1024: 1.1.1.3 root 1025: // Decompressor 1026: byte *decompressor = MapResource ("BIN", IDR_BOOT_LOADER_DECOMPRESSOR, &size); 1.1.1.12! root 1027: if (!decompressor || size > TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) 1.1 root 1028: throw ParameterIncorrect (SRC_POS); 1029: 1.1.1.12! root 1030: memcpy (buffer + TC_SECTOR_SIZE_BIOS, decompressor, size); 1.1 root 1031: 1.1.1.3 root 1032: // Compressed boot loader 1033: byte *bootLoader = MapResource ("BIN", bootLoaderId, &size); 1.1.1.12! root 1034: if (!bootLoader || size > TC_MAX_BOOT_LOADER_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) 1.1.1.3 root 1035: throw ParameterIncorrect (SRC_POS); 1.1 root 1036: 1.1.1.12! root 1037: memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS, bootLoader, size); 1.1 root 1038: 1.1.1.3 root 1039: // Boot loader and decompressor checksum 1040: *(uint16 *) (buffer + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET) = static_cast <uint16> (size); 1.1.1.12! root 1041: *(uint32 *) (buffer + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET) = GetChecksum (buffer + TC_SECTOR_SIZE_BIOS, ! 1042: TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS + size); 1.1.1.3 root 1043: 1044: // Backup of decompressor and boot loader 1.1.1.12! root 1045: if (size + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS <= TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) 1.1.1.3 root 1046: { 1.1.1.12! root 1047: memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS, ! 1048: buffer + TC_SECTOR_SIZE_BIOS, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS); 1.1.1.3 root 1049: 1050: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE; 1051: } 1.1.1.5 root 1052: else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER) 1.1.1.3 root 1053: { 1054: throw ParameterIncorrect (SRC_POS); 1055: } 1056: } 1057: 1058: 1.1.1.8 root 1059: void BootEncryption::ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig, string *customUserMessage, uint16 *bootLoaderVersion) 1.1.1.5 root 1060: { 1.1.1.6 root 1061: if (config && bufLength < TC_BOOT_CFG_FLAG_AREA_SIZE) 1.1.1.5 root 1062: throw ParameterIncorrect (SRC_POS); 1063: 1064: GetSystemDriveConfigurationRequest request; 1065: _snwprintf (request.DevicePath, array_capacity (request.DevicePath), L"%hs", GetSystemDriveConfiguration().DeviceKernelPath.c_str()); 1066: 1067: try 1068: { 1069: CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request)); 1.1.1.6 root 1070: if (config) 1071: *config = request.Configuration; 1072: 1073: if (userConfig) 1074: *userConfig = request.UserConfiguration; 1075: 1076: if (customUserMessage) 1077: { 1078: request.CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0; 1079: *customUserMessage = request.CustomUserMessage; 1080: } 1.1.1.8 root 1081: 1082: if (bootLoaderVersion) 1083: *bootLoaderVersion = request.BootLoaderVersion; 1.1.1.5 root 1084: } 1085: catch (...) 1086: { 1.1.1.6 root 1087: if (config) 1088: *config = 0; 1089: 1090: if (userConfig) 1091: *userConfig = 0; 1092: 1093: if (customUserMessage) 1094: customUserMessage->clear(); 1.1.1.8 root 1095: 1096: if (bootLoaderVersion) 1097: *bootLoaderVersion = 0; 1.1.1.5 root 1098: } 1099: } 1100: 1101: 1102: void BootEncryption::WriteBootSectorConfig (const byte newConfig[]) 1103: { 1104: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.12! root 1105: byte mbr[TC_SECTOR_SIZE_BIOS]; 1.1.1.5 root 1106: 1107: device.SeekAt (0); 1108: device.Read (mbr, sizeof (mbr)); 1109: 1110: memcpy (mbr + TC_BOOT_SECTOR_CONFIG_OFFSET, newConfig, TC_BOOT_CFG_FLAG_AREA_SIZE); 1111: 1112: device.SeekAt (0); 1113: device.Write (mbr, sizeof (mbr)); 1114: 1.1.1.12! root 1115: byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS]; 1.1.1.5 root 1116: device.SeekAt (0); 1117: device.Read (mbrVerificationBuf, sizeof (mbr)); 1118: 1119: if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0) 1120: throw ErrorException ("ERROR_MBR_PROTECTED"); 1121: } 1122: 1123: 1.1.1.6 root 1124: void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage) 1125: { 1126: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.12! root 1127: byte mbr[TC_SECTOR_SIZE_BIOS]; 1.1.1.6 root 1128: 1129: device.SeekAt (0); 1130: device.Read (mbr, sizeof (mbr)); 1131: 1.1.1.8 root 1132: if (!BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME) 1.1.1.12! root 1133: || BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET)) != VERSION_NUM) 1.1.1.8 root 1134: { 1135: return; 1136: } 1137: 1.1.1.6 root 1138: mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = userConfig; 1139: 1140: memset (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, 0, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); 1141: 1142: if (!customUserMessage.empty()) 1143: { 1144: if (customUserMessage.size() > TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH) 1145: throw ParameterIncorrect (SRC_POS); 1146: 1147: memcpy (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, customUserMessage.c_str(), customUserMessage.size()); 1148: } 1149: 1150: device.SeekAt (0); 1151: device.Write (mbr, sizeof (mbr)); 1152: 1.1.1.12! root 1153: byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS]; 1.1.1.6 root 1154: device.SeekAt (0); 1155: device.Read (mbrVerificationBuf, sizeof (mbr)); 1156: 1157: if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0) 1158: throw ErrorException ("ERROR_MBR_PROTECTED"); 1159: } 1160: 1161: 1.1.1.5 root 1162: unsigned int BootEncryption::GetHiddenOSCreationPhase () 1163: { 1164: byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE]; 1165: 1166: ReadBootSectorConfig (configFlags, sizeof(configFlags)); 1167: 1168: return (configFlags[0] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE); 1169: } 1170: 1171: 1172: void BootEncryption::SetHiddenOSCreationPhase (unsigned int newPhase) 1173: { 1174: #if TC_BOOT_CFG_FLAG_AREA_SIZE != 1 1175: # error TC_BOOT_CFG_FLAG_AREA_SIZE != 1; revise GetHiddenOSCreationPhase() and SetHiddenOSCreationPhase() 1176: #endif 1177: byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE]; 1178: 1179: ReadBootSectorConfig (configFlags, sizeof(configFlags)); 1180: 1181: configFlags[0] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE; 1182: 1183: configFlags[0] |= newPhase; 1184: 1185: WriteBootSectorConfig (configFlags); 1186: } 1187: 1188: 1.1.1.6 root 1189: #ifndef SETUP 1190: 1191: void BootEncryption::StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm) 1192: { 1193: if (!IsHiddenOSRunning()) 1194: throw ParameterIncorrect (SRC_POS); 1195: 1196: WipeDecoySystemRequest request; 1197: ZeroMemory (&request, sizeof (request)); 1198: 1199: request.WipeAlgorithm = wipeAlgorithm; 1200: 1201: if (Randinit() != ERR_SUCCESS) 1202: throw ParameterIncorrect (SRC_POS); 1203: 1.1.1.8 root 1204: UserEnrichRandomPool (ParentWindow); 1205: 1.1.1.6 root 1206: if (!RandgetBytes (request.WipeKey, sizeof (request.WipeKey), TRUE)) 1207: throw ParameterIncorrect (SRC_POS); 1208: 1209: CallDriver (TC_IOCTL_START_DECOY_SYSTEM_WIPE, &request, sizeof (request), NULL, 0); 1210: 1211: burn (&request, sizeof (request)); 1212: } 1213: 1214: 1215: void BootEncryption::AbortDecoyOSWipe () 1216: { 1217: CallDriver (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE); 1218: } 1219: 1220: 1221: DecoySystemWipeStatus BootEncryption::GetDecoyOSWipeStatus () 1222: { 1223: DecoySystemWipeStatus status; 1224: CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS, NULL, 0, &status, sizeof (status)); 1225: return status; 1226: } 1227: 1228: 1229: void BootEncryption::CheckDecoyOSWipeResult () 1230: { 1231: CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT); 1232: } 1233: 1234: 1235: void BootEncryption::WipeHiddenOSCreationConfig () 1236: { 1237: if (IsHiddenOSRunning() || Randinit() != ERR_SUCCESS) 1238: throw ParameterIncorrect (SRC_POS); 1239: 1240: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.12! root 1241: byte mbr[TC_SECTOR_SIZE_BIOS]; 1.1.1.6 root 1242: 1243: device.SeekAt (0); 1244: device.Read (mbr, sizeof (mbr)); 1245: 1246: finally_do_arg (BootEncryption *, this, 1247: { 1248: try 1249: { 1250: finally_arg->SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); 1251: } catch (...) { } 1252: }); 1253: 1254: #if PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE 1255: # error PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE 1256: #endif 1257: 1258: byte randData[PRAND_DISK_WIPE_PASSES]; 1259: if (!RandgetBytes (randData, sizeof (randData), FALSE)) 1260: throw ParameterIncorrect (SRC_POS); 1261: 1262: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++) 1263: { 1264: for (int i = 0; i < TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE; ++i) 1265: { 1266: mbr[TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + i] = randData[wipePass]; 1267: } 1268: 1269: mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE; 1270: mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] |= randData[wipePass] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE; 1271: 1272: if (wipePass == PRAND_DISK_WIPE_PASSES - 1) 1273: memset (mbr + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, 0, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE); 1274: 1275: device.SeekAt (0); 1276: device.Write (mbr, sizeof (mbr)); 1277: } 1278: 1279: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES/4 + 1; wipePass++) 1280: { 1281: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); 1282: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_CLONING); 1283: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPING); 1284: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPED); 1285: } 1286: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); 1287: } 1288: 1289: #endif // !SETUP 1290: 1291: 1292: void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation) 1.1.1.3 root 1293: { 1.1.1.5 root 1294: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1.1.6 root 1295: CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation); 1.1.1.3 root 1296: 1297: // Write MBR 1298: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.12! root 1299: byte mbr[TC_SECTOR_SIZE_BIOS]; 1.1 root 1300: 1301: device.SeekAt (0); 1.1.1.3 root 1302: device.Read (mbr, sizeof (mbr)); 1.1 root 1303: 1.1.1.8 root 1304: if (preserveUserConfig && BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME)) 1.1.1.6 root 1305: { 1306: uint16 version = BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET)); 1307: if (version != 0) 1308: { 1309: bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; 1310: memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); 1311: } 1312: } 1313: 1.1.1.3 root 1314: memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE); 1.1 root 1315: 1.1.1.3 root 1316: device.SeekAt (0); 1317: device.Write (mbr, sizeof (mbr)); 1.1 root 1318: 1.1.1.12! root 1319: byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS]; 1.1.1.3 root 1320: device.SeekAt (0); 1321: device.Read (mbrVerificationBuf, sizeof (mbr)); 1.1 root 1322: 1.1.1.3 root 1323: if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0) 1324: throw ErrorException ("ERROR_MBR_PROTECTED"); 1.1 root 1325: 1.1.1.3 root 1326: // Write boot loader 1.1.1.12! root 1327: device.SeekAt (TC_SECTOR_SIZE_BIOS); ! 1328: device.Write (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, sizeof (bootLoaderBuf) - TC_SECTOR_SIZE_BIOS); 1.1 root 1329: } 1330: 1331: 1332: string BootEncryption::GetSystemLoaderBackupPath () 1333: { 1334: char pathBuf[MAX_PATH]; 1335: 1336: throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf))); 1337: 1338: string path = string (pathBuf) + "\\" TC_APP_NAME; 1339: CreateDirectory (path.c_str(), NULL); 1340: 1341: return path + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME; 1342: } 1343: 1.1.1.3 root 1344: 1.1.1.5 root 1345: void BootEncryption::RenameDeprecatedSystemLoaderBackup () 1346: { 1347: char pathBuf[MAX_PATH]; 1348: 1349: if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, pathBuf))) 1350: { 1351: string path = string (pathBuf) + "\\" TC_APP_NAME + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY; 1352: 1353: if (FileExists (path.c_str()) && !FileExists (GetSystemLoaderBackupPath().c_str())) 1354: throw_sys_if (rename (path.c_str(), GetSystemLoaderBackupPath().c_str()) != 0); 1355: } 1356: } 1357: 1358: 1.1.1.2 root 1359: #ifndef SETUP 1.1 root 1360: void BootEncryption::CreateRescueIsoImage (bool initialSetup, const string &isoImagePath) 1361: { 1362: BootEncryptionStatus encStatus = GetStatus(); 1363: if (encStatus.SetupInProgress) 1364: throw ParameterIncorrect (SRC_POS); 1365: 1366: Buffer imageBuf (RescueIsoImageSize); 1367: 1368: byte *image = imageBuf.Ptr(); 1369: memset (image, 0, RescueIsoImageSize); 1370: 1371: // Primary volume descriptor 1.1.1.2 root 1372: strcpy ((char *)image + 0x8000, "\001CD001\001"); 1373: strcpy ((char *)image + 0x7fff + 41, "TrueCrypt Rescue Disk "); 1374: *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048; 1375: *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048); 1376: image[0x7fff + 121] = 1; 1377: image[0x7fff + 124] = 1; 1378: image[0x7fff + 125] = 1; 1379: image[0x7fff + 128] = 1; 1380: image[0x7fff + 130] = 8; 1381: image[0x7fff + 131] = 8; 1382: 1383: image[0x7fff + 133] = 10; 1384: image[0x7fff + 140] = 10; 1385: image[0x7fff + 141] = 0x14; 1386: image[0x7fff + 157] = 0x22; 1387: image[0x7fff + 159] = 0x18; 1.1 root 1388: 1389: // Boot record volume descriptor 1390: strcpy ((char *)image + 0x8801, "CD001\001EL TORITO SPECIFICATION"); 1391: image[0x8800 + 0x47] = 0x19; 1392: 1.1.1.2 root 1393: // Volume descriptor set terminator 1394: strcpy ((char *)image + 0x9000, "\377CD001\001"); 1395: 1396: // Path table 1397: image[0xA000 + 0] = 1; 1398: image[0xA000 + 2] = 0x18; 1399: image[0xA000 + 6] = 1; 1400: 1401: // Root directory 1402: image[0xc000 + 0] = 0x22; 1403: image[0xc000 + 2] = 0x18; 1404: image[0xc000 + 9] = 0x18; 1405: image[0xc000 + 11] = 0x08; 1406: image[0xc000 + 16] = 0x08; 1407: image[0xc000 + 25] = 0x02; 1408: image[0xc000 + 28] = 0x01; 1409: image[0xc000 + 31] = 0x01; 1410: image[0xc000 + 32] = 0x01; 1411: image[0xc000 + 34] = 0x22; 1412: image[0xc000 + 36] = 0x18; 1413: image[0xc000 + 43] = 0x18; 1414: image[0xc000 + 45] = 0x08; 1415: image[0xc000 + 50] = 0x08; 1416: image[0xc000 + 59] = 0x02; 1417: image[0xc000 + 62] = 0x01; 1418: *(uint32 *) (image + 0xc000 + 65) = 0x010101; 1419: 1.1 root 1420: // Validation entry 1421: image[0xc800] = 1; 1.1.1.2 root 1422: int offset = 0xc800 + 0x1c; 1.1 root 1423: image[offset++] = 0xaa; 1424: image[offset++] = 0x55; 1425: image[offset++] = 0x55; 1426: image[offset] = 0xaa; 1427: 1428: // Initial entry 1429: offset = 0xc820; 1430: image[offset++] = 0x88; 1431: image[offset++] = 2; 1432: image[0xc820 + 6] = 1; 1433: image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR; 1434: 1435: // TrueCrypt Boot Loader 1.1.1.5 root 1436: CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true); 1.1 root 1437: 1438: // Volume header 1439: if (initialSetup) 1440: { 1441: if (!RescueVolumeHeaderValid) 1442: throw ParameterIncorrect (SRC_POS); 1443: 1.1.1.5 root 1444: memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); 1.1 root 1445: } 1446: else 1447: { 1448: Device bootDevice (GetSystemDriveConfiguration().DevicePath, true); 1449: bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1.1.1.5 root 1450: bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); 1.1 root 1451: } 1452: 1453: // Original system loader 1454: try 1455: { 1456: File sysBakFile (GetSystemLoaderBackupPath(), true); 1457: sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE); 1458: 1459: image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER; 1460: } 1461: catch (Exception &e) 1462: { 1463: e.Show (ParentWindow); 1464: Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK"); 1465: } 1466: 1.1.1.5 root 1467: // Boot loader backup 1468: CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false); 1469: 1.1 root 1470: RescueIsoImage = new byte[RescueIsoImageSize]; 1471: if (!RescueIsoImage) 1472: throw bad_alloc(); 1473: memcpy (RescueIsoImage, image, RescueIsoImageSize); 1474: 1475: if (!isoImagePath.empty()) 1476: { 1477: File isoFile (isoImagePath, false, true); 1478: isoFile.Write (image, RescueIsoImageSize); 1479: } 1480: } 1.1.1.2 root 1481: #endif 1.1 root 1482: 1.1.1.12! root 1483: ! 1484: bool BootEncryption::IsCDDrivePresent () ! 1485: { ! 1486: for (char drive = 'Z'; drive >= 'C'; --drive) ! 1487: { ! 1488: string path = "X:\\"; ! 1489: path[0] = drive; ! 1490: ! 1491: if (GetDriveType (path.c_str()) == DRIVE_CDROM) ! 1492: return true; ! 1493: } ! 1494: ! 1495: return false; ! 1496: } ! 1497: ! 1498: 1.1 root 1499: bool BootEncryption::VerifyRescueDisk () 1500: { 1501: if (!RescueIsoImage) 1502: throw ParameterIncorrect (SRC_POS); 1503: 1.1.1.12! root 1504: for (char drive = 'Z'; drive >= 'C'; --drive) 1.1 root 1505: { 1506: try 1507: { 1508: string path = "X:"; 1509: path[0] = drive; 1510: 1511: Device driveDevice (path, true); 1512: size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; 1513: Buffer buffer ((verifiedSectorCount + 1) * 2048); 1514: 1515: DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size()); 1516: if (bytesRead != buffer.Size()) 1517: continue; 1518: 1519: if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) 1520: return true; 1521: } 1522: catch (...) { } 1523: } 1524: 1525: return false; 1526: } 1527: 1528: 1529: #ifndef SETUP 1530: 1531: void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5) 1532: { 1533: PCRYPTO_INFO cryptoInfo = NULL; 1.1.1.5 root 1534: 1.1.1.8 root 1535: if (!IsRandomNumberGeneratorStarted()) 1536: throw ParameterIncorrect (SRC_POS); 1537: 1.1.1.6 root 1538: throw_sys_if (CreateVolumeHeaderInMemory (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, &cryptoInfo, 1.1.1.12! root 1539: volumeSize, 0, encryptedAreaStart, 0, TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION, TC_HEADER_FLAG_ENCRYPTED_SYSTEM, TC_SECTOR_SIZE_BIOS, FALSE) != 0); 1.1 root 1540: 1541: finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); }); 1542: 1543: // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize) 1544: memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader)); 1.1.1.6 root 1545: ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo); 1.1 root 1546: 1547: DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); 1548: 1549: if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545) 1550: throw ParameterIncorrect (SRC_POS); 1551: 1552: byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; 1553: mputInt64 (fieldPos, volumeSize); 1.1.1.5 root 1554: 1555: // CRC of the header fields 1556: uint32 crc = GetCrc32 (RescueVolumeHeader + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); 1557: fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_HEADER_CRC; 1558: mputLong (fieldPos, crc); 1559: 1.1 root 1560: EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); 1561: 1562: VolumeHeaderValid = true; 1563: RescueVolumeHeaderValid = true; 1564: } 1565: 1566: 1567: void BootEncryption::InstallVolumeHeader () 1568: { 1569: if (!VolumeHeaderValid) 1570: throw ParameterIncorrect (SRC_POS); 1571: 1572: Device device (GetSystemDriveConfiguration().DevicePath); 1573: 1574: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1575: device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader)); 1576: } 1577: 1578: 1579: // For synchronous operations use AbortSetupWait() 1580: void BootEncryption::AbortSetup () 1581: { 1582: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); 1583: } 1584: 1585: 1586: // For asynchronous operations use AbortSetup() 1587: void BootEncryption::AbortSetupWait () 1588: { 1589: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); 1590: 1591: BootEncryptionStatus encStatus = GetStatus(); 1592: 1593: while (encStatus.SetupInProgress) 1594: { 1595: Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL); 1596: encStatus = GetStatus(); 1597: } 1598: } 1599: 1600: 1601: void BootEncryption::BackupSystemLoader () 1602: { 1603: Device device (GetSystemDriveConfiguration().DevicePath, true); 1604: 1.1.1.12! root 1605: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS]; 1.1 root 1606: 1607: device.SeekAt (0); 1608: device.Read (bootLoaderBuf, sizeof (bootLoaderBuf)); 1609: 1610: // Prevent TrueCrypt loader from being backed up 1611: for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i) 1612: { 1613: if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) 1614: { 1615: if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO) 1616: throw UserAbort (SRC_POS); 1617: return; 1618: } 1619: } 1620: 1621: File backupFile (GetSystemLoaderBackupPath(), false, true); 1622: backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); 1623: } 1624: 1625: 1626: void BootEncryption::RestoreSystemLoader () 1627: { 1.1.1.12! root 1628: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS]; 1.1 root 1629: 1630: File backupFile (GetSystemLoaderBackupPath(), true); 1631: 1632: if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf)) 1633: throw ParameterIncorrect (SRC_POS); 1634: 1635: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.4 root 1636: 1637: // Preserve current partition table 1.1.1.12! root 1638: byte mbr[TC_SECTOR_SIZE_BIOS]; 1.1.1.4 root 1639: device.SeekAt (0); 1640: device.Read (mbr, sizeof (mbr)); 1641: memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE); 1642: 1.1 root 1643: device.SeekAt (0); 1644: device.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); 1645: } 1646: 1.1.1.3 root 1647: #endif // SETUP 1.1 root 1648: 1.1.1.12! root 1649: void BootEncryption::RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid) 1.1 root 1650: { 1.1.1.12! root 1651: string filter; ! 1652: string filterReg; ! 1653: HKEY regKey; ! 1654: ! 1655: switch (filterType) ! 1656: { ! 1657: case DriveFilter: ! 1658: case VolumeFilter: ! 1659: filter = "truecrypt"; ! 1660: filterReg = "UpperFilters"; ! 1661: regKey = SetupDiOpenClassRegKey (deviceClassGuid, KEY_READ | KEY_WRITE); ! 1662: throw_sys_if (regKey == INVALID_HANDLE_VALUE); ! 1663: ! 1664: break; ! 1665: ! 1666: case DumpFilter: ! 1667: if (!IsOSAtLeast (WIN_VISTA)) ! 1668: return; 1.1 root 1669: 1.1.1.12! root 1670: filter = "truecrypt.sys"; ! 1671: filterReg = "DumpFilters"; ! 1672: SetLastError (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\CrashControl", 0, KEY_READ | KEY_WRITE, ®Key)); ! 1673: throw_sys_if (GetLastError() != ERROR_SUCCESS); ! 1674: ! 1675: break; ! 1676: ! 1677: default: ! 1678: throw ParameterIncorrect (SRC_POS); ! 1679: } ! 1680: ! 1681: finally_do_arg (HKEY, regKey, { RegCloseKey (finally_arg); }); ! 1682: ! 1683: if (registerFilter && filterType != DumpFilter) 1.1 root 1684: { 1.1.1.5 root 1685: // Register class filter below all other filters in the stack 1686: 1.1.1.12! root 1687: size_t strSize = filter.size() + 1; 1.1 root 1688: byte regKeyBuf[65536]; 1689: DWORD size = sizeof (regKeyBuf) - strSize; 1690: 1691: // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly 1.1.1.12! root 1692: strncpy ((char *) regKeyBuf, filter.c_str(), sizeof (regKeyBuf)); 1.1 root 1693: 1.1.1.12! root 1694: if (RegQueryValueEx (regKey, filterReg.c_str(), NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS) 1.1 root 1695: size = 1; 1696: 1.1.1.12! root 1697: SetLastError (RegSetValueEx (regKey, filterReg.c_str(), 0, REG_MULTI_SZ, regKeyBuf, strSize + size)); ! 1698: throw_sys_if (GetLastError() != ERROR_SUCCESS); 1.1 root 1699: } 1700: else 1701: { 1.1.1.12! root 1702: string infFileName = GetTempPath() + "\\truecrypt_driver_setup.inf"; 1.1 root 1703: 1704: File infFile (infFileName, false, true); 1.1.1.5 root 1705: finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); }); 1.1 root 1706: 1.1.1.5 root 1707: string infTxt = "[truecrypt]\r\n" 1.1.1.12! root 1708: + string (registerFilter ? "Add" : "Del") + "Reg=truecrypt_reg\r\n\r\n" 1.1.1.5 root 1709: "[truecrypt_reg]\r\n" 1.1.1.12! root 1710: "HKR,,\"" + filterReg + "\",0x0001" + string (registerFilter ? "0008" : "8002") + ",\"" + filter + "\"\r\n"; 1.1 root 1711: 1712: infFile.Write ((byte *) infTxt.c_str(), infTxt.size()); 1713: infFile.Close(); 1714: 1715: HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); 1716: throw_sys_if (hInf == INVALID_HANDLE_VALUE); 1717: finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); }); 1718: 1.1.1.12! root 1719: throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, regKey, NULL, 0, NULL, NULL, NULL, NULL)); 1.1 root 1720: } 1721: } 1.1.1.12! root 1722: ! 1723: void BootEncryption::RegisterFilterDriver (bool registerDriver, FilterType filterType) 1.1.1.5 root 1724: { 1725: if (!IsAdmin() && IsUacSupported()) 1726: { 1.1.1.12! root 1727: Elevator::RegisterFilterDriver (registerDriver, filterType); 1.1.1.5 root 1728: return; 1729: } 1730: 1.1.1.12! root 1731: switch (filterType) 1.1.1.5 root 1732: { 1.1.1.12! root 1733: case DriveFilter: ! 1734: RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_DISKDRIVE); ! 1735: break; ! 1736: ! 1737: case VolumeFilter: ! 1738: RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_VOLUME); ! 1739: RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_FLOPPYDISK); ! 1740: break; ! 1741: ! 1742: case DumpFilter: ! 1743: RegisterFilter (registerDriver, filterType); ! 1744: break; ! 1745: ! 1746: default: ! 1747: throw ParameterIncorrect (SRC_POS); 1.1.1.5 root 1748: } 1749: } 1.1 root 1750: 1.1.1.3 root 1751: #ifndef SETUP 1.1 root 1752: 1.1.1.10 root 1753: void BootEncryption::RegisterSystemFavoritesService (BOOL registerService) 1754: { 1755: if (!IsAdmin() && IsUacSupported()) 1756: { 1757: Elevator::RegisterSystemFavoritesService (registerService); 1758: return; 1759: } 1760: 1761: SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); 1762: throw_sys_if (!scm); 1763: 1.1.1.11 root 1764: string servicePath = GetServiceConfigPath (TC_APP_NAME ".exe"); 1765: 1.1.1.10 root 1766: if (registerService) 1767: { 1.1.1.12! root 1768: try ! 1769: { ! 1770: RegisterSystemFavoritesService (FALSE); ! 1771: } ! 1772: catch (...) { } ! 1773: 1.1.1.10 root 1774: char appPath[TC_MAX_PATH]; 1775: throw_sys_if (!GetModuleFileName (NULL, appPath, sizeof (appPath))); 1776: 1.1.1.11 root 1777: throw_sys_if (!CopyFile (appPath, servicePath.c_str(), FALSE)); 1778: 1.1.1.10 root 1779: SC_HANDLE service = CreateService (scm, 1780: TC_SYSTEM_FAVORITES_SERVICE_NAME, 1781: TC_APP_NAME " System Favorites", 1782: SERVICE_ALL_ACCESS, 1783: SERVICE_WIN32_OWN_PROCESS, 1784: SERVICE_AUTO_START, 1785: SERVICE_ERROR_NORMAL, 1.1.1.11 root 1786: (string ("\"") + servicePath + "\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(), 1.1.1.10 root 1787: TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP, 1788: NULL, 1789: NULL, 1790: NULL, 1791: NULL); 1792: 1793: throw_sys_if (!service); 1794: 1795: SERVICE_DESCRIPTION description; 1796: description.lpDescription = "Mounts TrueCrypt system favorite volumes."; 1797: ChangeServiceConfig2 (service, SERVICE_CONFIG_DESCRIPTION, &description); 1798: 1799: CloseServiceHandle (service); 1800: 1801: try 1802: { 1.1.1.12! root 1803: WriteLocalMachineRegistryString ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, "Service", FALSE); ! 1804: WriteLocalMachineRegistryString ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, "Service", FALSE); ! 1805: 1.1.1.10 root 1806: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, true); 1807: } 1808: catch (...) 1809: { 1810: try 1811: { 1812: RegisterSystemFavoritesService (false); 1813: } 1814: catch (...) { } 1815: 1816: throw; 1817: } 1818: } 1819: else 1820: { 1821: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, false); 1822: 1.1.1.12! root 1823: DeleteLocalMachineRegistryKey ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal", TC_SYSTEM_FAVORITES_SERVICE_NAME); ! 1824: DeleteLocalMachineRegistryKey ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network", TC_SYSTEM_FAVORITES_SERVICE_NAME); ! 1825: 1.1.1.10 root 1826: SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS); 1827: throw_sys_if (!service); 1828: 1829: throw_sys_if (!DeleteService (service)); 1830: CloseServiceHandle (service); 1.1.1.11 root 1831: 1832: DeleteFile (servicePath.c_str()); 1.1.1.10 root 1833: } 1834: } 1835: 1.1 root 1836: void BootEncryption::CheckRequirements () 1837: { 1838: if (nCurrentOS == WIN_2000) 1839: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS"); 1.1.1.8 root 1840: 1841: if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) 1842: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0"); 1.1 root 1843: 1844: if (IsNonInstallMode()) 1845: throw ErrorException ("FEATURE_REQUIRES_INSTALLATION"); 1846: 1847: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1848: 1849: if (config.SystemPartition.IsGPT) 1850: throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED"); 1851: 1.1.1.5 root 1852: if (SystemDriveIsDynamic()) 1853: throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK"); 1854: 1.1 root 1855: if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE) 1856: throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER"); 1857: 1858: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 1859: 1.1.1.12! root 1860: if (geometry.BytesPerSector != TC_SECTOR_SIZE_BIOS) ! 1861: throw ErrorException ("SYSENC_UNSUPPORTED_SECTOR_SIZE_BIOS"); 1.1 root 1862: 1.1.1.10 root 1863: bool activePartitionFound = false; 1.1.1.5 root 1864: if (!config.SystemPartition.IsGPT) 1865: { 1866: // Determine whether there is an Active partition on the system drive 1867: foreach (const Partition &partition, config.Partitions) 1868: { 1869: if (partition.Info.BootIndicator) 1870: { 1871: activePartitionFound = true; 1872: break; 1873: } 1874: } 1.1.1.10 root 1875: } 1876: 1877: if (!config.SystemLoaderPresent || !activePartitionFound) 1878: { 1879: static bool confirmed = false; 1880: 1881: if (!confirmed && AskWarnNoYes ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR") == IDNO) 1882: throw UserAbort (SRC_POS); 1.1.1.5 root 1883: 1.1.1.10 root 1884: confirmed = true; 1.1.1.5 root 1885: } 1886: } 1887: 1888: 1889: void BootEncryption::CheckRequirementsHiddenOS () 1890: { 1891: // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT). 1892: 1893: // The user may have modified/added/deleted partitions since the partition table was last scanned. 1894: InvalidateCachedSysDriveProperties (); 1895: 1896: GetPartitionForHiddenOS (); 1.1 root 1897: } 1898: 1899: 1.1.1.6 root 1900: void BootEncryption::InitialSecurityChecksForHiddenOS () 1901: { 1.1.1.10 root 1902: char windowsDrive = (char) toupper (GetWindowsDirectory()[0]); 1.1.1.6 root 1903: 1904: // Paging files 1.1.1.8 root 1905: bool pagingFilesOk = !IsPagingFileActive (TRUE); 1.1.1.6 root 1906: 1907: char pagingFileRegData[65536]; 1908: DWORD pagingFileRegDataSize = sizeof (pagingFileRegData); 1909: 1910: if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFileRegData, &pagingFileRegDataSize) 1911: && pagingFileRegDataSize > 4) 1912: { 1913: for (size_t i = 1; i < pagingFileRegDataSize - 2; ++i) 1914: { 1915: if (memcmp (pagingFileRegData + i, ":\\", 2) == 0 && toupper (pagingFileRegData[i - 1]) != windowsDrive) 1916: { 1.1.1.8 root 1917: pagingFilesOk = false; 1918: break; 1.1.1.6 root 1919: } 1920: } 1921: } 1922: 1.1.1.8 root 1923: if (!pagingFilesOk) 1924: { 1925: if (AskWarnYesNoString ((wchar_t *) (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1926: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION") 1927: + L"\n\n\n" 1928: + GetString ("RESTRICT_PAGING_FILES_TO_SYS_PARTITION") 1929: ).c_str()) == IDYES) 1930: { 1931: RestrictPagingFilesToSystemPartition(); 1932: RestartComputer(); 1933: AbortProcessSilent(); 1934: } 1935: 1936: throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1937: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1938: } 1939: 1.1.1.6 root 1940: // User profile 1941: char *configPath = GetConfigPath ("dummy"); 1942: if (configPath && toupper (configPath[0]) != windowsDrive) 1943: { 1944: throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION")) 1945: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1946: } 1947: 1948: // Temporary files 1949: if (toupper (GetTempPath()[0]) != windowsDrive) 1950: { 1951: throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION")) 1952: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1953: } 1954: } 1955: 1956: 1.1 root 1957: void BootEncryption::Deinstall () 1958: { 1959: BootEncryptionStatus encStatus = GetStatus(); 1960: 1961: if (encStatus.DriveEncrypted || encStatus.DriveMounted) 1962: throw ParameterIncorrect (SRC_POS); 1963: 1964: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1965: 1966: if (encStatus.VolumeHeaderPresent) 1967: { 1968: // Verify CRC of header salt 1969: Device device (config.DevicePath, true); 1.1.1.5 root 1970: byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 1971: 1972: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1973: device.Read (header, sizeof (header)); 1974: 1975: if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE)) 1976: throw ParameterIncorrect (SRC_POS); 1977: } 1978: 1.1.1.12! root 1979: try ! 1980: { ! 1981: RegisterFilterDriver (false, DriveFilter); ! 1982: RegisterFilterDriver (false, VolumeFilter); ! 1983: RegisterFilterDriver (false, DumpFilter); ! 1984: SetDriverServiceStartType (SERVICE_SYSTEM_START); ! 1985: } ! 1986: catch (...) ! 1987: { ! 1988: try ! 1989: { ! 1990: RegisterBootDriver (IsHiddenSystemRunning()); ! 1991: } ! 1992: catch (...) { } ! 1993: ! 1994: throw; ! 1995: } 1.1 root 1996: 1.1.1.5 root 1997: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails 1998: 1.1 root 1999: try 2000: { 1.1.1.10 root 2001: RegisterSystemFavoritesService (false); 2002: } 2003: catch (...) { } 2004: 2005: try 2006: { 1.1 root 2007: RestoreSystemLoader (); 2008: } 2009: catch (Exception &e) 2010: { 2011: e.Show (ParentWindow); 2012: throw ErrorException ("SYS_LOADER_RESTORE_FAILED"); 2013: } 1.1.1.10 root 2014: 1.1 root 2015: } 2016: 2017: 2018: int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5) 2019: { 1.1.1.5 root 2020: BootEncryptionStatus encStatus = GetStatus(); 2021: 2022: if (encStatus.SetupInProgress) 1.1 root 2023: throw ParameterIncorrect (SRC_POS); 2024: 2025: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 2026: 1.1.1.5 root 2027: char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 2028: Device device (config.DevicePath); 2029: 2030: // Only one algorithm is currently supported 2031: if (pkcs5 != 0) 2032: throw ParameterIncorrect (SRC_POS); 2033: 1.1.1.5 root 2034: int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; 2035: int64 backupHeaderOffset = -1; 2036: 2037: if (encStatus.HiddenSystem) 2038: { 2039: headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; 2040: 2041: // Find hidden system partition 2042: foreach (const Partition &partition, config.Partitions) 2043: { 2044: if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart) 2045: { 2046: backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE; 2047: break; 2048: } 2049: } 2050: 2051: if (backupHeaderOffset == -1) 2052: throw ParameterIncorrect (SRC_POS); 2053: } 2054: 2055: device.SeekAt (headerOffset); 1.1 root 2056: device.Read ((byte *) header, sizeof (header)); 2057: 2058: PCRYPTO_INFO cryptoInfo = NULL; 2059: 1.1.1.6 root 2060: int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, &cryptoInfo, NULL); 1.1 root 2061: finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); 2062: 2063: if (status != 0) 2064: { 2065: handleError (ParentWindow, status); 2066: return status; 2067: } 2068: 2069: // Change the PKCS-5 PRF if requested by user 2070: if (pkcs5 != 0) 1.1.1.8 root 2071: { 1.1 root 2072: cryptoInfo->pkcs5 = pkcs5; 1.1.1.8 root 2073: RandSetHashFunction (pkcs5); 2074: } 1.1 root 2075: 2076: throw_sys_if (Randinit () != 0); 1.1.1.8 root 2077: finally_do ({ RandStop (FALSE); }); 2078: 2079: NormalCursor(); 2080: UserEnrichRandomPool (ParentWindow); 2081: WaitCursor(); 1.1 root 2082: 2083: /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 2084: techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy 2085: to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22 2086: times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might 2087: impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the 2088: valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman 2089: recommends. During each pass we will write a valid working header. Each pass will use the same master 2090: key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only 2091: item that will be different for each pass will be the salt. This is sufficient to cause each "version" 2092: of the header to differ substantially and in a random manner from the versions written during the 2093: other passes. */ 2094: 2095: bool headerUpdated = false; 2096: int result = ERR_SUCCESS; 2097: 2098: try 2099: { 1.1.1.5 root 2100: BOOL backupHeader = FALSE; 2101: while (TRUE) 1.1 root 2102: { 1.1.1.5 root 2103: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++) 1.1 root 2104: { 1.1.1.5 root 2105: PCRYPTO_INFO tmpCryptoInfo = NULL; 2106: 1.1.1.6 root 2107: status = CreateVolumeHeaderInMemory (!encStatus.HiddenSystem, 1.1.1.5 root 2108: header, 2109: cryptoInfo->ea, 2110: cryptoInfo->mode, 2111: newPassword, 2112: cryptoInfo->pkcs5, 2113: (char *) cryptoInfo->master_keydata, 2114: &tmpCryptoInfo, 2115: cryptoInfo->VolumeSize.Value, 2116: cryptoInfo->hiddenVolumeSize, 2117: cryptoInfo->EncryptedAreaStart.Value, 2118: cryptoInfo->EncryptedAreaLength.Value, 2119: cryptoInfo->RequiredProgramVersion, 2120: cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM, 1.1.1.12! root 2121: cryptoInfo->SectorSize, 1.1.1.5 root 2122: wipePass < PRAND_DISK_WIPE_PASSES - 1); 2123: 2124: if (tmpCryptoInfo) 2125: crypto_close (tmpCryptoInfo); 2126: 2127: if (status != 0) 2128: { 2129: handleError (ParentWindow, status); 2130: return status; 2131: } 2132: 2133: device.SeekAt (headerOffset); 2134: device.Write ((byte *) header, sizeof (header)); 2135: headerUpdated = true; 1.1 root 2136: } 2137: 1.1.1.5 root 2138: if (!encStatus.HiddenSystem || backupHeader) 2139: break; 2140: 2141: backupHeader = TRUE; 2142: headerOffset = backupHeaderOffset; 1.1 root 2143: } 2144: } 2145: catch (Exception &e) 2146: { 2147: e.Show (ParentWindow); 2148: result = ERR_OS_ERROR; 2149: } 2150: 2151: if (headerUpdated) 2152: { 2153: ReopenBootVolumeHeaderRequest reopenRequest; 2154: reopenRequest.VolumePassword = *newPassword; 2155: finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); }); 2156: 2157: CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest)); 2158: } 2159: 2160: return result; 2161: } 2162: 2163: 2164: void BootEncryption::CheckEncryptionSetupResult () 2165: { 1.1.1.7 root 2166: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); 1.1 root 2167: } 2168: 2169: 1.1.1.6 root 2170: void BootEncryption::Install (bool hiddenSystem) 1.1 root 2171: { 2172: BootEncryptionStatus encStatus = GetStatus(); 2173: if (encStatus.DriveMounted) 2174: throw ParameterIncorrect (SRC_POS); 2175: 2176: try 2177: { 1.1.1.6 root 2178: InstallBootLoader (false, hiddenSystem); 2179: 2180: if (!hiddenSystem) 2181: InstallVolumeHeader (); 2182: 2183: RegisterBootDriver (hiddenSystem); 1.1 root 2184: } 2185: catch (Exception &) 2186: { 2187: try 2188: { 2189: RestoreSystemLoader (); 2190: } 2191: catch (Exception &e) 2192: { 2193: e.Show (ParentWindow); 2194: } 2195: 2196: throw; 2197: } 2198: } 2199: 2200: 1.1.1.6 root 2201: void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5) 2202: { 2203: BootEncryptionStatus encStatus = GetStatus(); 2204: if (encStatus.DriveMounted) 2205: throw ParameterIncorrect (SRC_POS); 2206: 2207: CheckRequirements(); 2208: BackupSystemLoader(); 2209: 2210: SelectedEncryptionAlgorithmId = ea; 2211: } 2212: 2213: 1.1 root 2214: void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath) 2215: { 2216: BootEncryptionStatus encStatus = GetStatus(); 2217: if (encStatus.DriveMounted) 2218: throw ParameterIncorrect (SRC_POS); 2219: 2220: CheckRequirements (); 2221: 2222: SystemDriveConfiguration config = GetSystemDriveConfiguration(); 1.1.1.7 root 2223: 2224: // Some chipset drivers may prevent access to the last sector of the drive 2225: if (!systemPartitionOnly) 2226: { 2227: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 2228: Buffer sector (geometry.BytesPerSector); 2229: 2230: Device device (config.DevicePath); 2231: 2232: try 2233: { 2234: device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector); 2235: device.Read (sector.Ptr(), sector.Size()); 2236: } 2237: catch (SystemException &e) 2238: { 2239: if (e.ErrorCode != ERROR_CRC) 2240: { 2241: e.Show (ParentWindow); 2242: Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS"); 2243: throw UserAbort (SRC_POS); 2244: } 2245: } 2246: } 2247: 1.1 root 2248: BackupSystemLoader (); 2249: 2250: uint64 volumeSize; 2251: uint64 encryptedAreaStart; 2252: 2253: if (systemPartitionOnly) 2254: { 2255: volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart; 2256: encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart; 2257: } 2258: else 2259: { 2260: volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE; 2261: encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE; 2262: } 2263: 1.1.1.3 root 2264: SelectedEncryptionAlgorithmId = ea; 1.1 root 2265: CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5); 2266: 2267: if (!rescueIsoImagePath.empty()) 2268: CreateRescueIsoImage (true, rescueIsoImagePath); 2269: } 2270: 1.1.1.6 root 2271: bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) 1.1.1.5 root 2272: { 2273: if (!IsAdmin() && IsUacSupported()) 1.1.1.6 root 2274: return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2275: 1.1.1.6 root 2276: return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2277: } 2278: 1.1.1.8 root 2279: void BootEncryption::RestrictPagingFilesToSystemPartition () 2280: { 2281: char pagingFiles[128]; 2282: strncpy (pagingFiles, "X:\\pagefile.sys 0 0", sizeof (pagingFiles)); 2283: pagingFiles[0] = GetWindowsDirectory()[0]; 2284: 2285: throw_sys_if (!WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFiles, strlen (pagingFiles) + 2)); 2286: } 1.1.1.5 root 2287: 2288: void BootEncryption::WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value) 2289: { 2290: if (!IsAdmin() && IsUacSupported()) 2291: { 2292: Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value); 2293: return; 2294: } 2295: 2296: throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value)); 2297: } 2298: 1.1.1.10 root 2299: void BootEncryption::SetDriverConfigurationFlag (uint32 flag, bool state) 2300: { 2301: DWORD configMap = ReadDriverConfigurationFlags(); 2302: 2303: if (state) 2304: configMap |= flag; 2305: else 2306: configMap &= ~flag; 2307: 2308: WriteLocalMachineRegistryDwordValue ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap); 2309: } 1.1.1.5 root 2310: 1.1.1.8 root 2311: void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors) 1.1 root 2312: { 2313: BootEncryptionStatus encStatus = GetStatus(); 2314: 2315: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2316: throw ParameterIncorrect (SRC_POS); 2317: 2318: BootEncryptionSetupRequest request; 2319: ZeroMemory (&request, sizeof (request)); 2320: 2321: request.SetupMode = SetupDecryption; 1.1.1.8 root 2322: request.DiscardUnreadableEncryptedSectors = discardUnreadableEncryptedSectors; 1.1 root 2323: 2324: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2325: } 2326: 1.1.1.6 root 2327: void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors) 1.1 root 2328: { 2329: BootEncryptionStatus encStatus = GetStatus(); 2330: 2331: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2332: throw ParameterIncorrect (SRC_POS); 2333: 2334: BootEncryptionSetupRequest request; 2335: ZeroMemory (&request, sizeof (request)); 2336: 2337: request.SetupMode = SetupEncryption; 2338: request.WipeAlgorithm = wipeAlgorithm; 1.1.1.6 root 2339: request.ZeroUnreadableSectors = zeroUnreadableSectors; 1.1 root 2340: 2341: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2342: } 2343: 1.1.1.10 root 2344: void BootEncryption::CopyFileAdmin (const string &sourceFile, const string &destinationFile) 2345: { 2346: if (!IsAdmin()) 2347: { 2348: if (!IsUacSupported()) 2349: { 2350: SetLastError (ERROR_ACCESS_DENIED); 2351: throw SystemException(); 2352: } 2353: else 2354: Elevator::CopyFile (sourceFile, destinationFile); 2355: } 2356: else 2357: throw_sys_if (!::CopyFile (sourceFile.c_str(), destinationFile.c_str(), FALSE)); 2358: } 2359: 2360: void BootEncryption::DeleteFileAdmin (const string &file) 2361: { 2362: if (!IsAdmin() && IsUacSupported()) 2363: Elevator::DeleteFile (file); 2364: else 2365: throw_sys_if (!::DeleteFile (file.c_str())); 2366: } 2367: 1.1.1.2 root 2368: #endif // !SETUP 1.1 root 2369: 1.1.1.12! root 2370: uint32 BootEncryption::ReadDriverConfigurationFlags () ! 2371: { ! 2372: DWORD configMap; ! 2373: ! 2374: if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap)) ! 2375: configMap = 0; ! 2376: ! 2377: return configMap; ! 2378: } 1.1.1.6 root 2379: 2380: void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data) 2381: { 2382: WriteBootDriveSectorRequest request; 2383: request.Offset.QuadPart = offset; 2384: memcpy (request.Data, data, sizeof (request.Data)); 2385: 2386: CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0); 2387: } 2388: 2389: void BootEncryption::RegisterBootDriver (bool hiddenSystem) 1.1.1.3 root 2390: { 2391: SetDriverServiceStartType (SERVICE_BOOT_START); 2392: 2393: try 2394: { 1.1.1.12! root 2395: RegisterFilterDriver (false, DriveFilter); ! 2396: RegisterFilterDriver (false, VolumeFilter); ! 2397: RegisterFilterDriver (false, DumpFilter); 1.1.1.3 root 2398: } 2399: catch (...) { } 2400: 1.1.1.12! root 2401: try ! 2402: { ! 2403: RegisterFilterDriver (true, DriveFilter); 1.1.1.6 root 2404: 1.1.1.12! root 2405: if (hiddenSystem) ! 2406: RegisterFilterDriver (true, VolumeFilter); ! 2407: ! 2408: RegisterFilterDriver (true, DumpFilter); ! 2409: } ! 2410: catch (...) ! 2411: { ! 2412: try { RegisterFilterDriver (false, DriveFilter); } catch (...) { } ! 2413: try { RegisterFilterDriver (false, VolumeFilter); } catch (...) { } ! 2414: try { RegisterFilterDriver (false, DumpFilter); } catch (...) { } ! 2415: try { SetDriverServiceStartType (SERVICE_SYSTEM_START); } catch (...) { } 1.1.1.3 root 2416: 1.1.1.12! root 2417: throw; ! 2418: } ! 2419: } 1.1.1.3 root 2420: 1.1 root 2421: bool BootEncryption::RestartComputer (void) 2422: { 1.1.1.5 root 2423: return (::RestartComputer() != FALSE); 1.1 root 2424: } 2425: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.