|
|
1.1 root 1: /* 1.1.1.8 root 2: Copyright (c) 2008-2009 TrueCrypt Foundation. All rights reserved. 1.1 root 3: 1.1.1.10! root 4: Governed by the TrueCrypt License 2.8 the full text of which is contained 1.1 root 5: in the file License.txt included in TrueCrypt binary and source code 6: distribution packages. 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: 138: static void RegisterFilterDriver (bool registerDriver, bool volumeClass) 139: { 140: Elevate(); 141: 142: DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE, volumeClass ? TRUE : FALSE); 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.5 root 226: static void RegisterFilterDriver (bool registerDriver, bool volumeClass) { 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: 323: while (size >= SECTOR_SIZE) 324: { 325: bootEnc.WriteBootDriveSector (FilePointerPosition, buffer); 326: 327: FilePointerPosition += SECTOR_SIZE; 328: buffer += SECTOR_SIZE; 329: size -= SECTOR_SIZE; 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) 385: delete RescueIsoImage; 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: 496: if (config.SystemPartition.Info.PartitionLength.QuadPart > TC_MAX_FAT_FS_SIZE) 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: if (Is64BitOs()) 580: driverPath = "SysWOW64" + driverPath.substr (driverPath.find ("\\")); 581: } 582: } 583: 1.1 root 584: throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, 1.1.1.5 root 585: startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL, 586: driverPath.empty() ? NULL : driverPath.c_str(), 1.1 root 587: startOnBoot ? "Filter" : NULL, 588: NULL, NULL, NULL, NULL, NULL)); 589: 590: // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER 591: throw_sys_if (!WriteLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", startType)); 592: } 593: 594: 595: void BootEncryption::ProbeRealSystemDriveSize () 596: { 597: if (RealSystemDriveSizeValid) 598: return; 599: 600: GetSystemDriveConfiguration(); 601: 602: ProbeRealDriveSizeRequest request; 603: _snwprintf (request.DeviceName, array_capacity (request.DeviceName), L"%hs", DriveConfig.DrivePartition.DevicePath.c_str()); 604: 605: CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request)); 606: DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize; 607: 1.1.1.5 root 608: RealSystemDriveSizeValid = true; 1.1.1.3 root 609: 610: if (request.TimeOut) 611: throw TimeOut (SRC_POS); 1.1 root 612: } 613: 614: 1.1.1.5 root 615: void BootEncryption::InvalidateCachedSysDriveProperties () 616: { 617: DriveConfigValid = false; 618: RealSystemDriveSizeValid = false; 619: } 620: 621: 1.1 root 622: PartitionList BootEncryption::GetDrivePartitions (int driveNumber) 623: { 624: PartitionList partList; 625: 626: for (int partNumber = 0; partNumber < 64; ++partNumber) 627: { 628: stringstream partPath; 629: partPath << "\\Device\\Harddisk" << driveNumber << "\\Partition" << partNumber; 630: 631: DISK_PARTITION_INFO_STRUCT diskPartInfo; 632: _snwprintf (diskPartInfo.deviceName, array_capacity (diskPartInfo.deviceName), L"%hs", partPath.str().c_str()); 633: 634: try 635: { 636: CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo)); 637: } 638: catch (...) 639: { 640: continue; 641: } 642: 643: Partition part; 644: part.DevicePath = partPath.str(); 645: part.Number = partNumber; 646: part.Info = diskPartInfo.partInfo; 647: part.IsGPT = diskPartInfo.IsGPT; 648: 649: // Mount point 650: wstringstream ws; 651: ws << partPath.str().c_str(); 652: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str()); 653: 654: if (driveNumber >= 0) 655: { 656: part.MountPoint += (char) (driveNumber + 'A'); 657: part.MountPoint += ":"; 658: } 1.1.1.8 root 659: 660: // Volume ID 661: wchar_t volumePath[TC_MAX_PATH]; 662: if (ResolveSymbolicLink ((wchar_t *) ws.str().c_str(), volumePath)) 663: { 664: wchar_t volumeName[TC_MAX_PATH]; 665: HANDLE fh = FindFirstVolumeW (volumeName, array_capacity (volumeName)); 666: if (fh != INVALID_HANDLE_VALUE) 667: { 668: do 669: { 670: wstring volumeNameStr = volumeName; 671: wchar_t devicePath[TC_MAX_PATH]; 672: 673: if (QueryDosDeviceW (volumeNameStr.substr (4, volumeNameStr.size() - 1 - 4).c_str(), devicePath, array_capacity (devicePath)) != 0 674: && wcscmp (volumePath, devicePath) == 0) 675: { 676: part.VolumeNameId = volumeName; 677: break; 678: } 679: 680: } while (FindNextVolumeW (fh, volumeName, array_capacity (volumeName))); 681: 682: FindVolumeClose (fh); 683: } 684: } 685: 1.1 root 686: partList.push_back (part); 687: } 688: 689: return partList; 690: } 691: 692: 693: DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber) 694: { 695: stringstream devName; 696: devName << "\\Device\\Harddisk" << driveNumber << "\\Partition0"; 697: 698: DISK_GEOMETRY geometry; 699: throw_sys_if (!::GetDriveGeometry ((char *) devName.str().c_str(), &geometry)); 700: return geometry; 701: } 702: 703: 704: string BootEncryption::GetWindowsDirectory () 705: { 706: char buf[MAX_PATH]; 1.1.1.5 root 707: throw_sys_if (GetSystemDirectory (buf, sizeof (buf)) == 0); 708: 709: return string (buf); 1.1 root 710: } 1.1.1.6 root 711: 712: 713: string BootEncryption::GetTempPath () 714: { 715: char tempPath[MAX_PATH]; 716: DWORD tempLen = ::GetTempPath (sizeof (tempPath), tempPath); 717: if (tempLen == 0 || tempLen > sizeof (tempPath)) 718: throw ParameterIncorrect (SRC_POS); 719: 720: return string (tempPath); 721: } 722: 1.1 root 723: 724: uint16 BootEncryption::GetInstalledBootLoaderVersion () 725: { 726: uint16 version; 727: CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version)); 728: return version; 729: } 730: 731: 1.1.1.3 root 732: // Note that this does not require admin rights (it just requires the driver to be running) 733: bool BootEncryption::IsBootLoaderOnDrive (char *devicePath) 734: { 735: try 736: { 737: OPEN_TEST_STRUCT openTestStruct; 1.1.1.8 root 738: memset (&openTestStruct, 0, sizeof (openTestStruct)); 1.1.1.3 root 739: DWORD dwResult; 740: 741: strcpy ((char *) &openTestStruct.wszFileName[0], devicePath); 742: ToUNICODE ((char *) &openTestStruct.wszFileName[0]); 743: 744: openTestStruct.bDetectTCBootLoader = TRUE; 745: 746: return (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, 747: &openTestStruct, sizeof (OPEN_TEST_STRUCT), 1.1.1.8 root 748: &openTestStruct, sizeof (OPEN_TEST_STRUCT), 749: &dwResult, NULL) && openTestStruct.TCBootLoaderDetected); 1.1.1.3 root 750: } 751: catch (...) 752: { 753: return false; 754: } 755: } 756: 757: 1.1 root 758: BootEncryptionStatus BootEncryption::GetStatus () 759: { 760: /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */ 761: 762: BootEncryptionStatus status; 763: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status)); 764: return status; 765: } 766: 767: 768: void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties) 769: { 770: if (properties == NULL) 771: throw ParameterIncorrect (SRC_POS); 772: 773: CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties)); 774: } 775: 776: 1.1.1.5 root 777: bool BootEncryption::IsHiddenSystemRunning () 778: { 779: int hiddenSystemStatus; 780: 781: CallDriver (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING, nullptr, 0, &hiddenSystemStatus, sizeof (hiddenSystemStatus)); 782: return hiddenSystemStatus != 0; 783: } 784: 785: 1.1.1.2 root 786: bool BootEncryption::SystemDriveContainsPartitionType (byte type) 787: { 788: Device device (GetSystemDriveConfiguration().DevicePath, true); 789: 790: byte mbrBuf[SECTOR_SIZE]; 791: device.SeekAt (0); 792: device.Read (mbrBuf, sizeof (mbrBuf)); 793: 794: MBR *mbr = reinterpret_cast <MBR *> (mbrBuf); 795: if (mbr->Signature != 0xaa55) 796: throw ParameterIncorrect (SRC_POS); 797: 798: for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i) 799: { 800: if (mbr->Partitions[i].Type == type) 801: return true; 802: } 803: 804: return false; 805: } 806: 807: 808: bool BootEncryption::SystemDriveContainsExtendedPartition () 809: { 810: return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED); 811: } 812: 813: 814: bool BootEncryption::SystemDriveIsDynamic () 815: { 1.1.1.5 root 816: GetSystemDriveConfigurationRequest request; 817: _snwprintf (request.DevicePath, array_capacity (request.DevicePath), L"%hs", GetSystemDriveConfiguration().DeviceKernelPath.c_str()); 818: 819: CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request)); 820: return request.DriveIsDynamic ? true : false; 1.1.1.2 root 821: } 822: 823: 1.1 root 824: SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration () 825: { 826: if (DriveConfigValid) 827: return DriveConfig; 828: 829: SystemDriveConfiguration config; 830: 831: string winDir = GetWindowsDirectory(); 832: 833: // Scan all drives 834: for (int driveNumber = 0; driveNumber < 32; ++driveNumber) 835: { 836: bool windowsFound = false; 1.1.1.10! root 837: bool activePartitionFound = false; ! 838: config.ExtraBootPartitionPresent = false; 1.1 root 839: config.SystemLoaderPresent = false; 840: 841: PartitionList partitions = GetDrivePartitions (driveNumber); 842: foreach (const Partition &part, partitions) 843: { 1.1.1.5 root 844: if (!part.MountPoint.empty() 845: && (_access ((part.MountPoint + "\\bootmgr").c_str(), 0) == 0 || _access ((part.MountPoint + "\\ntldr").c_str(), 0) == 0)) 846: { 1.1 root 847: config.SystemLoaderPresent = true; 1.1.1.5 root 848: } 1.1.1.8 root 849: else if (!part.VolumeNameId.empty() 850: && (_waccess ((part.VolumeNameId + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.VolumeNameId + L"\\ntldr").c_str(), 0) == 0)) 851: { 852: config.SystemLoaderPresent = true; 853: } 1.1 root 854: 1.1.1.6 root 855: if (!windowsFound && !part.MountPoint.empty() && ToUpperCase (winDir).find (ToUpperCase (part.MountPoint)) == 0) 1.1 root 856: { 857: config.SystemPartition = part; 858: windowsFound = true; 859: } 1.1.1.10! root 860: ! 861: if (!activePartitionFound && part.Info.BootIndicator) ! 862: { ! 863: activePartitionFound = true; ! 864: ! 865: if (part.Info.PartitionLength.QuadPart > 0 && part.Info.PartitionLength.QuadPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE) ! 866: config.ExtraBootPartitionPresent = true; ! 867: } 1.1 root 868: } 869: 870: if (windowsFound) 871: { 872: config.DriveNumber = driveNumber; 873: 874: stringstream ss; 875: ss << "PhysicalDrive" << driveNumber; 876: config.DevicePath = ss.str(); 877: 1.1.1.5 root 878: stringstream kernelPath; 879: kernelPath << "\\Device\\Harddisk" << driveNumber << "\\Partition0"; 880: config.DeviceKernelPath = kernelPath.str(); 881: 1.1 root 882: config.DrivePartition = partitions.front(); 883: partitions.pop_front(); 884: config.Partitions = partitions; 885: 886: config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull; 887: config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart; 888: 889: foreach (const Partition &part, config.Partitions) 890: { 891: if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace) 892: config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart; 893: 894: config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart; 895: } 896: 897: DriveConfig = config; 1.1.1.5 root 898: DriveConfigValid = true; 1.1 root 899: return DriveConfig; 900: } 901: } 902: 903: throw ParameterIncorrect (SRC_POS); 904: } 905: 906: 907: bool BootEncryption::SystemPartitionCoversWholeDrive () 908: { 909: SystemDriveConfiguration config = GetSystemDriveConfiguration(); 910: 1.1.1.10! root 911: if (IsOSAtLeast (WIN_7) ! 912: && config.Partitions.size() == 2 ! 913: && config.ExtraBootPartitionPresent ! 914: && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 164 * BYTES_PER_MB) ! 915: { ! 916: return true; ! 917: } ! 918: 1.1 root 919: return config.Partitions.size() == 1 1.1.1.3 root 920: && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * BYTES_PER_MB; 1.1 root 921: } 922: 923: 1.1.1.3 root 924: uint32 BootEncryption::GetChecksum (byte *data, size_t size) 1.1 root 925: { 1.1.1.3 root 926: uint32 sum = 0; 927: 928: while (size-- > 0) 929: { 930: sum += *data++; 931: sum = _rotl (sum, 1); 932: } 933: 934: return sum; 935: } 936: 937: 1.1.1.6 root 938: void BootEncryption::CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation) 1.1.1.3 root 939: { 1.1.1.5 root 940: if (bufferSize < TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE) 1.1.1.3 root 941: throw ParameterIncorrect (SRC_POS); 942: 943: ZeroMemory (buffer, bufferSize); 944: 945: int ea = 0; 946: if (GetStatus().DriveMounted) 947: { 948: try 949: { 950: GetBootEncryptionAlgorithmNameRequest request; 951: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request)); 952: 953: if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0) 954: ea = AES; 955: else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0) 956: ea = SERPENT; 957: else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0) 958: ea = TWOFISH; 959: } 960: catch (...) 961: { 962: try 963: { 964: VOLUME_PROPERTIES_STRUCT properties; 965: GetVolumeProperties (&properties); 966: ea = properties.ea; 967: } 968: catch (...) { } 969: } 970: } 971: else 972: { 973: if (SelectedEncryptionAlgorithmId == 0) 974: throw ParameterIncorrect (SRC_POS); 975: 976: ea = SelectedEncryptionAlgorithmId; 977: } 978: 1.1.1.5 root 979: int bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR; 980: int bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER; 1.1.1.3 root 981: 982: switch (ea) 983: { 984: case AES: 1.1.1.5 root 985: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES; 986: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES; 1.1.1.3 root 987: break; 988: 989: case SERPENT: 1.1.1.5 root 990: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT; 991: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT; 1.1.1.3 root 992: break; 993: 994: case TWOFISH: 1.1.1.5 root 995: bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH; 996: bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH; 1.1.1.3 root 997: break; 998: } 999: 1000: // Boot sector 1.1 root 1001: DWORD size; 1.1.1.3 root 1002: byte *bootSecResourceImg = MapResource ("BIN", bootSectorId, &size); 1003: if (!bootSecResourceImg || size != SECTOR_SIZE) 1004: throw ParameterIncorrect (SRC_POS); 1005: 1006: memcpy (buffer, bootSecResourceImg, size); 1.1 root 1007: 1.1.1.6 root 1008: *(uint16 *) (buffer + TC_BOOT_SECTOR_VERSION_OFFSET) = BE16 (VERSION_NUM); 1009: 1.1.1.8 root 1010: if (IsOSAtLeast (WIN_VISTA)) 1.1.1.3 root 1011: buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER; 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); 1017: byte headerSector[SECTOR_SIZE]; 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); 1027: if (!decompressor || size > TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE) 1.1 root 1028: throw ParameterIncorrect (SRC_POS); 1029: 1.1.1.3 root 1030: memcpy (buffer + SECTOR_SIZE, decompressor, size); 1.1 root 1031: 1.1.1.3 root 1032: // Compressed boot loader 1033: byte *bootLoader = MapResource ("BIN", bootLoaderId, &size); 1034: if (!bootLoader || size > TC_MAX_BOOT_LOADER_SECTOR_COUNT * SECTOR_SIZE) 1035: throw ParameterIncorrect (SRC_POS); 1.1 root 1036: 1.1.1.3 root 1037: memcpy (buffer + SECTOR_SIZE + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE, 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); 1041: *(uint32 *) (buffer + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET) = GetChecksum (buffer + SECTOR_SIZE, 1042: TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE + size); 1043: 1044: // Backup of decompressor and boot loader 1045: if (size + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * SECTOR_SIZE <= TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE) 1046: { 1047: memcpy (buffer + SECTOR_SIZE + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE, 1048: buffer + SECTOR_SIZE, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * SECTOR_SIZE); 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); 1105: byte mbr[SECTOR_SIZE]; 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: 1115: byte mbrVerificationBuf[SECTOR_SIZE]; 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); 1127: byte mbr[SECTOR_SIZE]; 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) 1133: || BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET)) > VERSION_NUM) 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: 1153: byte mbrVerificationBuf[SECTOR_SIZE]; 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); 1241: byte mbr[SECTOR_SIZE]; 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); 1299: byte mbr[SECTOR_SIZE]; 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.3 root 1319: byte mbrVerificationBuf[SECTOR_SIZE]; 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 root 1327: device.SeekAt (SECTOR_SIZE); 1.1.1.3 root 1328: device.Write (bootLoaderBuf + SECTOR_SIZE, sizeof (bootLoaderBuf) - SECTOR_SIZE); 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: 1483: bool BootEncryption::VerifyRescueDisk () 1484: { 1485: if (!RescueIsoImage) 1486: throw ParameterIncorrect (SRC_POS); 1487: 1488: for (char drive = 'Z'; drive >= 'D'; --drive) 1489: { 1490: try 1491: { 1492: string path = "X:"; 1493: path[0] = drive; 1494: 1495: Device driveDevice (path, true); 1496: size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; 1497: Buffer buffer ((verifiedSectorCount + 1) * 2048); 1498: 1499: DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size()); 1500: if (bytesRead != buffer.Size()) 1501: continue; 1502: 1503: if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) 1504: return true; 1505: } 1506: catch (...) { } 1507: } 1508: 1509: return false; 1510: } 1511: 1512: 1513: #ifndef SETUP 1514: 1515: void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5) 1516: { 1517: PCRYPTO_INFO cryptoInfo = NULL; 1.1.1.5 root 1518: 1.1.1.8 root 1519: if (!IsRandomNumberGeneratorStarted()) 1520: throw ParameterIncorrect (SRC_POS); 1521: 1.1.1.6 root 1522: throw_sys_if (CreateVolumeHeaderInMemory (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, &cryptoInfo, 1.1.1.5 root 1523: volumeSize, 0, encryptedAreaStart, 0, TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION, TC_HEADER_FLAG_ENCRYPTED_SYSTEM, FALSE) != 0); 1.1 root 1524: 1525: finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); }); 1526: 1527: // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize) 1528: memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader)); 1.1.1.6 root 1529: ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo); 1.1 root 1530: 1531: DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); 1532: 1533: if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545) 1534: throw ParameterIncorrect (SRC_POS); 1535: 1536: byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; 1537: mputInt64 (fieldPos, volumeSize); 1.1.1.5 root 1538: 1539: // CRC of the header fields 1540: uint32 crc = GetCrc32 (RescueVolumeHeader + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); 1541: fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_HEADER_CRC; 1542: mputLong (fieldPos, crc); 1543: 1.1 root 1544: EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); 1545: 1546: VolumeHeaderValid = true; 1547: RescueVolumeHeaderValid = true; 1548: } 1549: 1550: 1551: void BootEncryption::InstallVolumeHeader () 1552: { 1553: if (!VolumeHeaderValid) 1554: throw ParameterIncorrect (SRC_POS); 1555: 1556: Device device (GetSystemDriveConfiguration().DevicePath); 1557: 1558: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1559: device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader)); 1560: } 1561: 1562: 1563: // For synchronous operations use AbortSetupWait() 1564: void BootEncryption::AbortSetup () 1565: { 1566: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); 1567: } 1568: 1569: 1570: // For asynchronous operations use AbortSetup() 1571: void BootEncryption::AbortSetupWait () 1572: { 1573: CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP); 1574: 1575: BootEncryptionStatus encStatus = GetStatus(); 1576: 1577: while (encStatus.SetupInProgress) 1578: { 1579: Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL); 1580: encStatus = GetStatus(); 1581: } 1582: } 1583: 1584: 1585: void BootEncryption::BackupSystemLoader () 1586: { 1587: Device device (GetSystemDriveConfiguration().DevicePath, true); 1588: 1589: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE]; 1590: 1591: device.SeekAt (0); 1592: device.Read (bootLoaderBuf, sizeof (bootLoaderBuf)); 1593: 1594: // Prevent TrueCrypt loader from being backed up 1595: for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i) 1596: { 1597: if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) 1598: { 1599: if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO) 1600: throw UserAbort (SRC_POS); 1601: return; 1602: } 1603: } 1604: 1605: File backupFile (GetSystemLoaderBackupPath(), false, true); 1606: backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); 1607: } 1608: 1609: 1610: void BootEncryption::RestoreSystemLoader () 1611: { 1612: byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE]; 1613: 1614: File backupFile (GetSystemLoaderBackupPath(), true); 1615: 1616: if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf)) 1617: throw ParameterIncorrect (SRC_POS); 1618: 1619: Device device (GetSystemDriveConfiguration().DevicePath); 1.1.1.4 root 1620: 1621: // Preserve current partition table 1622: byte mbr[SECTOR_SIZE]; 1623: device.SeekAt (0); 1624: device.Read (mbr, sizeof (mbr)); 1625: memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE); 1626: 1.1 root 1627: device.SeekAt (0); 1628: device.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); 1629: } 1630: 1.1.1.3 root 1631: #endif // SETUP 1.1 root 1632: 1.1.1.5 root 1633: void BootEncryption::RegisterDeviceClassFilter (bool registerFilter, const GUID *deviceClassGuid) 1.1 root 1634: { 1.1.1.5 root 1635: HKEY classRegKey = SetupDiOpenClassRegKey (deviceClassGuid, KEY_READ | KEY_WRITE); 1.1 root 1636: throw_sys_if (classRegKey == INVALID_HANDLE_VALUE); 1637: finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); }); 1638: 1.1.1.5 root 1639: if (registerFilter) 1.1 root 1640: { 1.1.1.5 root 1641: // Register class filter below all other filters in the stack 1642: 1.1 root 1643: size_t strSize = strlen ("truecrypt") + 1; 1644: byte regKeyBuf[65536]; 1645: DWORD size = sizeof (regKeyBuf) - strSize; 1646: 1647: // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly 1648: strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf)); 1649: 1650: if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS) 1651: size = 1; 1652: 1653: throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS); 1654: } 1655: else 1656: { 1.1.1.5 root 1657: // Unregister a class filter 1.1.1.6 root 1658: string infFileName = GetTempPath() + "\\truecrypt_device_filter.inf"; 1.1 root 1659: 1660: File infFile (infFileName, false, true); 1.1.1.5 root 1661: finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); }); 1.1 root 1662: 1.1.1.5 root 1663: string infTxt = "[truecrypt]\r\n" 1664: "DelReg=truecrypt_reg\r\n\r\n" 1665: "[truecrypt_reg]\r\n" 1666: "HKR,,\"UpperFilters\",0x00018002,\"truecrypt\"\r\n"; 1.1 root 1667: 1668: infFile.Write ((byte *) infTxt.c_str(), infTxt.size()); 1669: infFile.Close(); 1670: 1671: HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); 1672: throw_sys_if (hInf == INVALID_HANDLE_VALUE); 1673: finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); }); 1674: 1675: throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL)); 1676: } 1677: } 1.1.1.5 root 1678: 1679: void BootEncryption::RegisterFilterDriver (bool registerDriver, bool volumeClass) 1680: { 1681: if (!IsAdmin() && IsUacSupported()) 1682: { 1683: Elevator::RegisterFilterDriver (registerDriver, volumeClass); 1684: return; 1685: } 1686: 1687: if (volumeClass) 1688: { 1689: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_VOLUME); 1690: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_FLOPPYDISK); 1691: } 1692: else 1693: { 1694: RegisterDeviceClassFilter (registerDriver, &GUID_DEVCLASS_DISKDRIVE); 1695: } 1696: } 1.1 root 1697: 1.1.1.3 root 1698: #ifndef SETUP 1.1 root 1699: 1.1.1.10! root 1700: void BootEncryption::RegisterSystemFavoritesService (BOOL registerService) ! 1701: { ! 1702: if (!IsAdmin() && IsUacSupported()) ! 1703: { ! 1704: Elevator::RegisterSystemFavoritesService (registerService); ! 1705: return; ! 1706: } ! 1707: ! 1708: SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); ! 1709: throw_sys_if (!scm); ! 1710: ! 1711: if (registerService) ! 1712: { ! 1713: char appPath[TC_MAX_PATH]; ! 1714: throw_sys_if (!GetModuleFileName (NULL, appPath, sizeof (appPath))); ! 1715: ! 1716: SC_HANDLE service = CreateService (scm, ! 1717: TC_SYSTEM_FAVORITES_SERVICE_NAME, ! 1718: TC_APP_NAME " System Favorites", ! 1719: SERVICE_ALL_ACCESS, ! 1720: SERVICE_WIN32_OWN_PROCESS, ! 1721: SERVICE_AUTO_START, ! 1722: SERVICE_ERROR_NORMAL, ! 1723: (string ("\"") + appPath + "\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(), ! 1724: TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP, ! 1725: NULL, ! 1726: NULL, ! 1727: NULL, ! 1728: NULL); ! 1729: ! 1730: throw_sys_if (!service); ! 1731: ! 1732: SERVICE_DESCRIPTION description; ! 1733: description.lpDescription = "Mounts TrueCrypt system favorite volumes."; ! 1734: ChangeServiceConfig2 (service, SERVICE_CONFIG_DESCRIPTION, &description); ! 1735: ! 1736: CloseServiceHandle (service); ! 1737: ! 1738: try ! 1739: { ! 1740: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, true); ! 1741: } ! 1742: catch (...) ! 1743: { ! 1744: try ! 1745: { ! 1746: RegisterSystemFavoritesService (false); ! 1747: } ! 1748: catch (...) { } ! 1749: ! 1750: throw; ! 1751: } ! 1752: } ! 1753: else ! 1754: { ! 1755: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, false); ! 1756: ! 1757: SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS); ! 1758: throw_sys_if (!service); ! 1759: ! 1760: throw_sys_if (!DeleteService (service)); ! 1761: CloseServiceHandle (service); ! 1762: } ! 1763: } ! 1764: 1.1 root 1765: void BootEncryption::CheckRequirements () 1766: { 1767: if (nCurrentOS == WIN_2000) 1768: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS"); 1.1.1.8 root 1769: 1770: if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) 1771: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0"); 1.1 root 1772: 1773: if (IsNonInstallMode()) 1774: throw ErrorException ("FEATURE_REQUIRES_INSTALLATION"); 1775: 1776: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1777: 1778: if (config.SystemPartition.IsGPT) 1779: throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED"); 1780: 1.1.1.5 root 1781: if (SystemDriveIsDynamic()) 1782: throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK"); 1783: 1.1 root 1784: if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE) 1785: throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER"); 1786: 1787: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 1788: 1789: if (geometry.BytesPerSector != SECTOR_SIZE) 1790: throw ErrorException ("LARGE_SECTOR_UNSUPPORTED"); 1791: 1.1.1.10! root 1792: bool activePartitionFound = false; 1.1.1.5 root 1793: if (!config.SystemPartition.IsGPT) 1794: { 1795: // Determine whether there is an Active partition on the system drive 1796: foreach (const Partition &partition, config.Partitions) 1797: { 1798: if (partition.Info.BootIndicator) 1799: { 1800: activePartitionFound = true; 1801: break; 1802: } 1803: } 1.1.1.10! root 1804: } ! 1805: ! 1806: if (!config.SystemLoaderPresent || !activePartitionFound) ! 1807: { ! 1808: static bool confirmed = false; ! 1809: ! 1810: if (!confirmed && AskWarnNoYes ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR") == IDNO) ! 1811: throw UserAbort (SRC_POS); 1.1.1.5 root 1812: 1.1.1.10! root 1813: confirmed = true; 1.1.1.5 root 1814: } 1815: } 1816: 1817: 1818: void BootEncryption::CheckRequirementsHiddenOS () 1819: { 1820: // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT). 1821: 1822: // The user may have modified/added/deleted partitions since the partition table was last scanned. 1823: InvalidateCachedSysDriveProperties (); 1824: 1825: GetPartitionForHiddenOS (); 1.1 root 1826: } 1827: 1828: 1.1.1.6 root 1829: void BootEncryption::InitialSecurityChecksForHiddenOS () 1830: { 1.1.1.10! root 1831: char windowsDrive = (char) toupper (GetWindowsDirectory()[0]); 1.1.1.6 root 1832: 1833: // Paging files 1.1.1.8 root 1834: bool pagingFilesOk = !IsPagingFileActive (TRUE); 1.1.1.6 root 1835: 1836: char pagingFileRegData[65536]; 1837: DWORD pagingFileRegDataSize = sizeof (pagingFileRegData); 1838: 1839: if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFileRegData, &pagingFileRegDataSize) 1840: && pagingFileRegDataSize > 4) 1841: { 1842: for (size_t i = 1; i < pagingFileRegDataSize - 2; ++i) 1843: { 1844: if (memcmp (pagingFileRegData + i, ":\\", 2) == 0 && toupper (pagingFileRegData[i - 1]) != windowsDrive) 1845: { 1.1.1.8 root 1846: pagingFilesOk = false; 1847: break; 1.1.1.6 root 1848: } 1849: } 1850: } 1851: 1.1.1.8 root 1852: if (!pagingFilesOk) 1853: { 1854: if (AskWarnYesNoString ((wchar_t *) (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1855: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION") 1856: + L"\n\n\n" 1857: + GetString ("RESTRICT_PAGING_FILES_TO_SYS_PARTITION") 1858: ).c_str()) == IDYES) 1859: { 1860: RestrictPagingFilesToSystemPartition(); 1861: RestartComputer(); 1862: AbortProcessSilent(); 1863: } 1864: 1865: throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1866: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1867: } 1868: 1.1.1.6 root 1869: // User profile 1870: char *configPath = GetConfigPath ("dummy"); 1871: if (configPath && toupper (configPath[0]) != windowsDrive) 1872: { 1873: throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION")) 1874: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1875: } 1876: 1877: // Temporary files 1878: if (toupper (GetTempPath()[0]) != windowsDrive) 1879: { 1880: throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION")) 1881: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1882: } 1883: } 1884: 1885: 1.1 root 1886: void BootEncryption::Deinstall () 1887: { 1888: BootEncryptionStatus encStatus = GetStatus(); 1889: 1890: if (encStatus.DriveEncrypted || encStatus.DriveMounted) 1891: throw ParameterIncorrect (SRC_POS); 1892: 1893: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1894: 1895: if (encStatus.VolumeHeaderPresent) 1896: { 1897: // Verify CRC of header salt 1898: Device device (config.DevicePath, true); 1.1.1.5 root 1899: byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 1900: 1901: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1902: device.Read (header, sizeof (header)); 1903: 1904: if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE)) 1905: throw ParameterIncorrect (SRC_POS); 1906: } 1907: 1.1.1.5 root 1908: RegisterFilterDriver (false, false); 1909: RegisterFilterDriver (false, true); 1.1 root 1910: SetDriverServiceStartType (SERVICE_SYSTEM_START); 1911: 1.1.1.5 root 1912: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails 1913: 1.1 root 1914: try 1915: { 1.1.1.10! root 1916: RegisterSystemFavoritesService (false); ! 1917: } ! 1918: catch (...) { } ! 1919: ! 1920: try ! 1921: { 1.1 root 1922: RestoreSystemLoader (); 1923: } 1924: catch (Exception &e) 1925: { 1926: e.Show (ParentWindow); 1927: throw ErrorException ("SYS_LOADER_RESTORE_FAILED"); 1928: } 1.1.1.10! root 1929: 1.1 root 1930: } 1931: 1932: 1933: int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5) 1934: { 1.1.1.5 root 1935: BootEncryptionStatus encStatus = GetStatus(); 1936: 1937: if (encStatus.SetupInProgress) 1.1 root 1938: throw ParameterIncorrect (SRC_POS); 1939: 1940: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1941: 1.1.1.5 root 1942: char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 1943: Device device (config.DevicePath); 1944: 1945: // Only one algorithm is currently supported 1946: if (pkcs5 != 0) 1947: throw ParameterIncorrect (SRC_POS); 1948: 1.1.1.5 root 1949: int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; 1950: int64 backupHeaderOffset = -1; 1951: 1952: if (encStatus.HiddenSystem) 1953: { 1954: headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; 1955: 1956: // Find hidden system partition 1957: foreach (const Partition &partition, config.Partitions) 1958: { 1959: if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart) 1960: { 1961: backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE; 1962: break; 1963: } 1964: } 1965: 1966: if (backupHeaderOffset == -1) 1967: throw ParameterIncorrect (SRC_POS); 1968: } 1969: 1970: device.SeekAt (headerOffset); 1.1 root 1971: device.Read ((byte *) header, sizeof (header)); 1972: 1973: PCRYPTO_INFO cryptoInfo = NULL; 1974: 1.1.1.6 root 1975: int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, &cryptoInfo, NULL); 1.1 root 1976: finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); 1977: 1978: if (status != 0) 1979: { 1980: handleError (ParentWindow, status); 1981: return status; 1982: } 1983: 1984: // Change the PKCS-5 PRF if requested by user 1985: if (pkcs5 != 0) 1.1.1.8 root 1986: { 1.1 root 1987: cryptoInfo->pkcs5 = pkcs5; 1.1.1.8 root 1988: RandSetHashFunction (pkcs5); 1989: } 1.1 root 1990: 1991: throw_sys_if (Randinit () != 0); 1.1.1.8 root 1992: finally_do ({ RandStop (FALSE); }); 1993: 1994: NormalCursor(); 1995: UserEnrichRandomPool (ParentWindow); 1996: WaitCursor(); 1.1 root 1997: 1998: /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 1999: techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy 2000: to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22 2001: times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might 2002: impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the 2003: valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman 2004: recommends. During each pass we will write a valid working header. Each pass will use the same master 2005: key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only 2006: item that will be different for each pass will be the salt. This is sufficient to cause each "version" 2007: of the header to differ substantially and in a random manner from the versions written during the 2008: other passes. */ 2009: 2010: bool headerUpdated = false; 2011: int result = ERR_SUCCESS; 2012: 2013: try 2014: { 1.1.1.5 root 2015: BOOL backupHeader = FALSE; 2016: while (TRUE) 1.1 root 2017: { 1.1.1.5 root 2018: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++) 1.1 root 2019: { 1.1.1.5 root 2020: PCRYPTO_INFO tmpCryptoInfo = NULL; 2021: 1.1.1.6 root 2022: status = CreateVolumeHeaderInMemory (!encStatus.HiddenSystem, 1.1.1.5 root 2023: header, 2024: cryptoInfo->ea, 2025: cryptoInfo->mode, 2026: newPassword, 2027: cryptoInfo->pkcs5, 2028: (char *) cryptoInfo->master_keydata, 2029: &tmpCryptoInfo, 2030: cryptoInfo->VolumeSize.Value, 2031: cryptoInfo->hiddenVolumeSize, 2032: cryptoInfo->EncryptedAreaStart.Value, 2033: cryptoInfo->EncryptedAreaLength.Value, 2034: cryptoInfo->RequiredProgramVersion, 2035: cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM, 2036: wipePass < PRAND_DISK_WIPE_PASSES - 1); 2037: 2038: if (tmpCryptoInfo) 2039: crypto_close (tmpCryptoInfo); 2040: 2041: if (status != 0) 2042: { 2043: handleError (ParentWindow, status); 2044: return status; 2045: } 2046: 2047: device.SeekAt (headerOffset); 2048: device.Write ((byte *) header, sizeof (header)); 2049: headerUpdated = true; 1.1 root 2050: } 2051: 1.1.1.5 root 2052: if (!encStatus.HiddenSystem || backupHeader) 2053: break; 2054: 2055: backupHeader = TRUE; 2056: headerOffset = backupHeaderOffset; 1.1 root 2057: } 2058: } 2059: catch (Exception &e) 2060: { 2061: e.Show (ParentWindow); 2062: result = ERR_OS_ERROR; 2063: } 2064: 2065: if (headerUpdated) 2066: { 2067: ReopenBootVolumeHeaderRequest reopenRequest; 2068: reopenRequest.VolumePassword = *newPassword; 2069: finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); }); 2070: 2071: CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest)); 2072: } 2073: 2074: return result; 2075: } 2076: 2077: 2078: void BootEncryption::CheckEncryptionSetupResult () 2079: { 1.1.1.7 root 2080: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); 1.1 root 2081: } 2082: 2083: 1.1.1.6 root 2084: void BootEncryption::Install (bool hiddenSystem) 1.1 root 2085: { 2086: BootEncryptionStatus encStatus = GetStatus(); 2087: if (encStatus.DriveMounted) 2088: throw ParameterIncorrect (SRC_POS); 2089: 2090: try 2091: { 1.1.1.6 root 2092: InstallBootLoader (false, hiddenSystem); 2093: 2094: if (!hiddenSystem) 2095: InstallVolumeHeader (); 2096: 2097: RegisterBootDriver (hiddenSystem); 1.1 root 2098: } 2099: catch (Exception &) 2100: { 2101: try 2102: { 2103: RestoreSystemLoader (); 2104: } 2105: catch (Exception &e) 2106: { 2107: e.Show (ParentWindow); 2108: } 2109: 2110: throw; 2111: } 2112: } 2113: 2114: 1.1.1.6 root 2115: void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5) 2116: { 2117: BootEncryptionStatus encStatus = GetStatus(); 2118: if (encStatus.DriveMounted) 2119: throw ParameterIncorrect (SRC_POS); 2120: 2121: CheckRequirements(); 2122: BackupSystemLoader(); 2123: 2124: SelectedEncryptionAlgorithmId = ea; 2125: } 2126: 2127: 1.1 root 2128: void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath) 2129: { 2130: BootEncryptionStatus encStatus = GetStatus(); 2131: if (encStatus.DriveMounted) 2132: throw ParameterIncorrect (SRC_POS); 2133: 2134: CheckRequirements (); 2135: 2136: SystemDriveConfiguration config = GetSystemDriveConfiguration(); 1.1.1.7 root 2137: 2138: // Some chipset drivers may prevent access to the last sector of the drive 2139: if (!systemPartitionOnly) 2140: { 2141: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 2142: Buffer sector (geometry.BytesPerSector); 2143: 2144: Device device (config.DevicePath); 2145: 2146: try 2147: { 2148: device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector); 2149: device.Read (sector.Ptr(), sector.Size()); 2150: } 2151: catch (SystemException &e) 2152: { 2153: if (e.ErrorCode != ERROR_CRC) 2154: { 2155: e.Show (ParentWindow); 2156: Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS"); 2157: throw UserAbort (SRC_POS); 2158: } 2159: } 2160: } 2161: 1.1 root 2162: BackupSystemLoader (); 2163: 2164: uint64 volumeSize; 2165: uint64 encryptedAreaStart; 2166: 2167: if (systemPartitionOnly) 2168: { 2169: volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart; 2170: encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart; 2171: } 2172: else 2173: { 2174: volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE; 2175: encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE; 2176: } 2177: 1.1.1.3 root 2178: SelectedEncryptionAlgorithmId = ea; 1.1 root 2179: CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5); 2180: 2181: if (!rescueIsoImagePath.empty()) 2182: CreateRescueIsoImage (true, rescueIsoImagePath); 2183: } 2184: 1.1.1.6 root 2185: bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) 1.1.1.5 root 2186: { 2187: if (!IsAdmin() && IsUacSupported()) 1.1.1.6 root 2188: return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2189: 1.1.1.6 root 2190: return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2191: } 2192: 1.1.1.8 root 2193: void BootEncryption::RestrictPagingFilesToSystemPartition () 2194: { 2195: char pagingFiles[128]; 2196: strncpy (pagingFiles, "X:\\pagefile.sys 0 0", sizeof (pagingFiles)); 2197: pagingFiles[0] = GetWindowsDirectory()[0]; 2198: 2199: throw_sys_if (!WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFiles, strlen (pagingFiles) + 2)); 2200: } 1.1.1.5 root 2201: 2202: void BootEncryption::WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value) 2203: { 2204: if (!IsAdmin() && IsUacSupported()) 2205: { 2206: Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value); 2207: return; 2208: } 2209: 2210: throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value)); 2211: } 2212: 1.1.1.10! root 2213: uint32 BootEncryption::ReadDriverConfigurationFlags () ! 2214: { ! 2215: DWORD configMap; ! 2216: ! 2217: if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap)) ! 2218: configMap = 0; ! 2219: ! 2220: return configMap; ! 2221: } ! 2222: ! 2223: void BootEncryption::SetDriverConfigurationFlag (uint32 flag, bool state) ! 2224: { ! 2225: DWORD configMap = ReadDriverConfigurationFlags(); ! 2226: ! 2227: if (state) ! 2228: configMap |= flag; ! 2229: else ! 2230: configMap &= ~flag; ! 2231: ! 2232: WriteLocalMachineRegistryDwordValue ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap); ! 2233: } 1.1.1.5 root 2234: 1.1.1.8 root 2235: void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors) 1.1 root 2236: { 2237: BootEncryptionStatus encStatus = GetStatus(); 2238: 2239: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2240: throw ParameterIncorrect (SRC_POS); 2241: 2242: BootEncryptionSetupRequest request; 2243: ZeroMemory (&request, sizeof (request)); 2244: 2245: request.SetupMode = SetupDecryption; 1.1.1.8 root 2246: request.DiscardUnreadableEncryptedSectors = discardUnreadableEncryptedSectors; 1.1 root 2247: 2248: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2249: } 2250: 1.1.1.6 root 2251: void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors) 1.1 root 2252: { 2253: BootEncryptionStatus encStatus = GetStatus(); 2254: 2255: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2256: throw ParameterIncorrect (SRC_POS); 2257: 2258: BootEncryptionSetupRequest request; 2259: ZeroMemory (&request, sizeof (request)); 2260: 2261: request.SetupMode = SetupEncryption; 2262: request.WipeAlgorithm = wipeAlgorithm; 1.1.1.6 root 2263: request.ZeroUnreadableSectors = zeroUnreadableSectors; 1.1 root 2264: 2265: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2266: } 2267: 1.1.1.10! root 2268: void BootEncryption::CopyFileAdmin (const string &sourceFile, const string &destinationFile) ! 2269: { ! 2270: if (!IsAdmin()) ! 2271: { ! 2272: if (!IsUacSupported()) ! 2273: { ! 2274: SetLastError (ERROR_ACCESS_DENIED); ! 2275: throw SystemException(); ! 2276: } ! 2277: else ! 2278: Elevator::CopyFile (sourceFile, destinationFile); ! 2279: } ! 2280: else ! 2281: throw_sys_if (!::CopyFile (sourceFile.c_str(), destinationFile.c_str(), FALSE)); ! 2282: } ! 2283: ! 2284: void BootEncryption::DeleteFileAdmin (const string &file) ! 2285: { ! 2286: if (!IsAdmin() && IsUacSupported()) ! 2287: Elevator::DeleteFile (file); ! 2288: else ! 2289: throw_sys_if (!::DeleteFile (file.c_str())); ! 2290: } ! 2291: 1.1.1.2 root 2292: #endif // !SETUP 1.1 root 2293: 1.1.1.6 root 2294: 2295: void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data) 2296: { 2297: WriteBootDriveSectorRequest request; 2298: request.Offset.QuadPart = offset; 2299: memcpy (request.Data, data, sizeof (request.Data)); 2300: 2301: CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0); 2302: } 2303: 2304: 2305: void BootEncryption::RegisterBootDriver (bool hiddenSystem) 1.1.1.3 root 2306: { 2307: SetDriverServiceStartType (SERVICE_BOOT_START); 2308: 2309: try 2310: { 1.1.1.5 root 2311: RegisterFilterDriver (false, false); 2312: RegisterFilterDriver (false, true); 1.1.1.3 root 2313: } 2314: catch (...) { } 2315: 1.1.1.5 root 2316: RegisterFilterDriver (true, false); 1.1.1.6 root 2317: 2318: if (hiddenSystem) 2319: RegisterFilterDriver (true, true); 1.1.1.3 root 2320: } 2321: 2322: 1.1 root 2323: bool BootEncryption::RestartComputer (void) 2324: { 1.1.1.5 root 2325: return (::RestartComputer() != FALSE); 1.1 root 2326: } 2327: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.