|
|
1.1 root 1: /* 1.1.1.11! root 2: Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. 1.1 root 3: 1.1.1.11! root 4: Governed by the TrueCrypt License 2.8 the full text of which is contained in ! 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: 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: 1.1.1.11! root 1711: string servicePath = GetServiceConfigPath (TC_APP_NAME ".exe"); ! 1712: 1.1.1.10 root 1713: if (registerService) 1714: { 1715: char appPath[TC_MAX_PATH]; 1716: throw_sys_if (!GetModuleFileName (NULL, appPath, sizeof (appPath))); 1717: 1.1.1.11! root 1718: throw_sys_if (!CopyFile (appPath, servicePath.c_str(), FALSE)); ! 1719: 1.1.1.10 root 1720: SC_HANDLE service = CreateService (scm, 1721: TC_SYSTEM_FAVORITES_SERVICE_NAME, 1722: TC_APP_NAME " System Favorites", 1723: SERVICE_ALL_ACCESS, 1724: SERVICE_WIN32_OWN_PROCESS, 1725: SERVICE_AUTO_START, 1726: SERVICE_ERROR_NORMAL, 1.1.1.11! root 1727: (string ("\"") + servicePath + "\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(), 1.1.1.10 root 1728: TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP, 1729: NULL, 1730: NULL, 1731: NULL, 1732: NULL); 1733: 1734: throw_sys_if (!service); 1735: 1736: SERVICE_DESCRIPTION description; 1737: description.lpDescription = "Mounts TrueCrypt system favorite volumes."; 1738: ChangeServiceConfig2 (service, SERVICE_CONFIG_DESCRIPTION, &description); 1739: 1740: CloseServiceHandle (service); 1741: 1742: try 1743: { 1744: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, true); 1745: } 1746: catch (...) 1747: { 1748: try 1749: { 1750: RegisterSystemFavoritesService (false); 1751: } 1752: catch (...) { } 1753: 1754: throw; 1755: } 1756: } 1757: else 1758: { 1759: SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, false); 1760: 1761: SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS); 1762: throw_sys_if (!service); 1763: 1764: throw_sys_if (!DeleteService (service)); 1765: CloseServiceHandle (service); 1.1.1.11! root 1766: ! 1767: DeleteFile (servicePath.c_str()); 1.1.1.10 root 1768: } 1769: } 1770: 1.1 root 1771: void BootEncryption::CheckRequirements () 1772: { 1773: if (nCurrentOS == WIN_2000) 1774: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS"); 1.1.1.8 root 1775: 1776: if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) 1777: throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0"); 1.1 root 1778: 1779: if (IsNonInstallMode()) 1780: throw ErrorException ("FEATURE_REQUIRES_INSTALLATION"); 1781: 1782: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1783: 1784: if (config.SystemPartition.IsGPT) 1785: throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED"); 1786: 1.1.1.5 root 1787: if (SystemDriveIsDynamic()) 1788: throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK"); 1789: 1.1 root 1790: if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE) 1791: throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER"); 1792: 1793: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 1794: 1795: if (geometry.BytesPerSector != SECTOR_SIZE) 1796: throw ErrorException ("LARGE_SECTOR_UNSUPPORTED"); 1797: 1.1.1.10 root 1798: bool activePartitionFound = false; 1.1.1.5 root 1799: if (!config.SystemPartition.IsGPT) 1800: { 1801: // Determine whether there is an Active partition on the system drive 1802: foreach (const Partition &partition, config.Partitions) 1803: { 1804: if (partition.Info.BootIndicator) 1805: { 1806: activePartitionFound = true; 1807: break; 1808: } 1809: } 1.1.1.10 root 1810: } 1811: 1812: if (!config.SystemLoaderPresent || !activePartitionFound) 1813: { 1814: static bool confirmed = false; 1815: 1816: if (!confirmed && AskWarnNoYes ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR") == IDNO) 1817: throw UserAbort (SRC_POS); 1.1.1.5 root 1818: 1.1.1.10 root 1819: confirmed = true; 1.1.1.5 root 1820: } 1821: } 1822: 1823: 1824: void BootEncryption::CheckRequirementsHiddenOS () 1825: { 1826: // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT). 1827: 1828: // The user may have modified/added/deleted partitions since the partition table was last scanned. 1829: InvalidateCachedSysDriveProperties (); 1830: 1831: GetPartitionForHiddenOS (); 1.1 root 1832: } 1833: 1834: 1.1.1.6 root 1835: void BootEncryption::InitialSecurityChecksForHiddenOS () 1836: { 1.1.1.10 root 1837: char windowsDrive = (char) toupper (GetWindowsDirectory()[0]); 1.1.1.6 root 1838: 1839: // Paging files 1.1.1.8 root 1840: bool pagingFilesOk = !IsPagingFileActive (TRUE); 1.1.1.6 root 1841: 1842: char pagingFileRegData[65536]; 1843: DWORD pagingFileRegDataSize = sizeof (pagingFileRegData); 1844: 1845: if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFileRegData, &pagingFileRegDataSize) 1846: && pagingFileRegDataSize > 4) 1847: { 1848: for (size_t i = 1; i < pagingFileRegDataSize - 2; ++i) 1849: { 1850: if (memcmp (pagingFileRegData + i, ":\\", 2) == 0 && toupper (pagingFileRegData[i - 1]) != windowsDrive) 1851: { 1.1.1.8 root 1852: pagingFilesOk = false; 1853: break; 1.1.1.6 root 1854: } 1855: } 1856: } 1857: 1.1.1.8 root 1858: if (!pagingFilesOk) 1859: { 1860: if (AskWarnYesNoString ((wchar_t *) (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1861: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION") 1862: + L"\n\n\n" 1863: + GetString ("RESTRICT_PAGING_FILES_TO_SYS_PARTITION") 1864: ).c_str()) == IDYES) 1865: { 1866: RestrictPagingFilesToSystemPartition(); 1867: RestartComputer(); 1868: AbortProcessSilent(); 1869: } 1870: 1871: throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION")) 1872: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1873: } 1874: 1.1.1.6 root 1875: // User profile 1876: char *configPath = GetConfigPath ("dummy"); 1877: if (configPath && toupper (configPath[0]) != windowsDrive) 1878: { 1879: throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION")) 1880: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1881: } 1882: 1883: // Temporary files 1884: if (toupper (GetTempPath()[0]) != windowsDrive) 1885: { 1886: throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION")) 1887: + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")); 1888: } 1889: } 1890: 1891: 1.1 root 1892: void BootEncryption::Deinstall () 1893: { 1894: BootEncryptionStatus encStatus = GetStatus(); 1895: 1896: if (encStatus.DriveEncrypted || encStatus.DriveMounted) 1897: throw ParameterIncorrect (SRC_POS); 1898: 1899: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1900: 1901: if (encStatus.VolumeHeaderPresent) 1902: { 1903: // Verify CRC of header salt 1904: Device device (config.DevicePath, true); 1.1.1.5 root 1905: byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 1906: 1907: device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET); 1908: device.Read (header, sizeof (header)); 1909: 1910: if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE)) 1911: throw ParameterIncorrect (SRC_POS); 1912: } 1913: 1.1.1.5 root 1914: RegisterFilterDriver (false, false); 1915: RegisterFilterDriver (false, true); 1.1 root 1916: SetDriverServiceStartType (SERVICE_SYSTEM_START); 1917: 1.1.1.5 root 1918: SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails 1919: 1.1 root 1920: try 1921: { 1.1.1.10 root 1922: RegisterSystemFavoritesService (false); 1923: } 1924: catch (...) { } 1925: 1926: try 1927: { 1.1 root 1928: RestoreSystemLoader (); 1929: } 1930: catch (Exception &e) 1931: { 1932: e.Show (ParentWindow); 1933: throw ErrorException ("SYS_LOADER_RESTORE_FAILED"); 1934: } 1.1.1.10 root 1935: 1.1 root 1936: } 1937: 1938: 1939: int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5) 1940: { 1.1.1.5 root 1941: BootEncryptionStatus encStatus = GetStatus(); 1942: 1943: if (encStatus.SetupInProgress) 1.1 root 1944: throw ParameterIncorrect (SRC_POS); 1945: 1946: SystemDriveConfiguration config = GetSystemDriveConfiguration (); 1947: 1.1.1.5 root 1948: char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; 1.1 root 1949: Device device (config.DevicePath); 1950: 1951: // Only one algorithm is currently supported 1952: if (pkcs5 != 0) 1953: throw ParameterIncorrect (SRC_POS); 1954: 1.1.1.5 root 1955: int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; 1956: int64 backupHeaderOffset = -1; 1957: 1958: if (encStatus.HiddenSystem) 1959: { 1960: headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; 1961: 1962: // Find hidden system partition 1963: foreach (const Partition &partition, config.Partitions) 1964: { 1965: if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart) 1966: { 1967: backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE; 1968: break; 1969: } 1970: } 1971: 1972: if (backupHeaderOffset == -1) 1973: throw ParameterIncorrect (SRC_POS); 1974: } 1975: 1976: device.SeekAt (headerOffset); 1.1 root 1977: device.Read ((byte *) header, sizeof (header)); 1978: 1979: PCRYPTO_INFO cryptoInfo = NULL; 1980: 1.1.1.6 root 1981: int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, &cryptoInfo, NULL); 1.1 root 1982: finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); 1983: 1984: if (status != 0) 1985: { 1986: handleError (ParentWindow, status); 1987: return status; 1988: } 1989: 1990: // Change the PKCS-5 PRF if requested by user 1991: if (pkcs5 != 0) 1.1.1.8 root 1992: { 1.1 root 1993: cryptoInfo->pkcs5 = pkcs5; 1.1.1.8 root 1994: RandSetHashFunction (pkcs5); 1995: } 1.1 root 1996: 1997: throw_sys_if (Randinit () != 0); 1.1.1.8 root 1998: finally_do ({ RandStop (FALSE); }); 1999: 2000: NormalCursor(); 2001: UserEnrichRandomPool (ParentWindow); 2002: WaitCursor(); 1.1 root 2003: 2004: /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 2005: techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy 2006: to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22 2007: times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might 2008: impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the 2009: valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman 2010: recommends. During each pass we will write a valid working header. Each pass will use the same master 2011: key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only 2012: item that will be different for each pass will be the salt. This is sufficient to cause each "version" 2013: of the header to differ substantially and in a random manner from the versions written during the 2014: other passes. */ 2015: 2016: bool headerUpdated = false; 2017: int result = ERR_SUCCESS; 2018: 2019: try 2020: { 1.1.1.5 root 2021: BOOL backupHeader = FALSE; 2022: while (TRUE) 1.1 root 2023: { 1.1.1.5 root 2024: for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++) 1.1 root 2025: { 1.1.1.5 root 2026: PCRYPTO_INFO tmpCryptoInfo = NULL; 2027: 1.1.1.6 root 2028: status = CreateVolumeHeaderInMemory (!encStatus.HiddenSystem, 1.1.1.5 root 2029: header, 2030: cryptoInfo->ea, 2031: cryptoInfo->mode, 2032: newPassword, 2033: cryptoInfo->pkcs5, 2034: (char *) cryptoInfo->master_keydata, 2035: &tmpCryptoInfo, 2036: cryptoInfo->VolumeSize.Value, 2037: cryptoInfo->hiddenVolumeSize, 2038: cryptoInfo->EncryptedAreaStart.Value, 2039: cryptoInfo->EncryptedAreaLength.Value, 2040: cryptoInfo->RequiredProgramVersion, 2041: cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM, 2042: wipePass < PRAND_DISK_WIPE_PASSES - 1); 2043: 2044: if (tmpCryptoInfo) 2045: crypto_close (tmpCryptoInfo); 2046: 2047: if (status != 0) 2048: { 2049: handleError (ParentWindow, status); 2050: return status; 2051: } 2052: 2053: device.SeekAt (headerOffset); 2054: device.Write ((byte *) header, sizeof (header)); 2055: headerUpdated = true; 1.1 root 2056: } 2057: 1.1.1.5 root 2058: if (!encStatus.HiddenSystem || backupHeader) 2059: break; 2060: 2061: backupHeader = TRUE; 2062: headerOffset = backupHeaderOffset; 1.1 root 2063: } 2064: } 2065: catch (Exception &e) 2066: { 2067: e.Show (ParentWindow); 2068: result = ERR_OS_ERROR; 2069: } 2070: 2071: if (headerUpdated) 2072: { 2073: ReopenBootVolumeHeaderRequest reopenRequest; 2074: reopenRequest.VolumePassword = *newPassword; 2075: finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); }); 2076: 2077: CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest)); 2078: } 2079: 2080: return result; 2081: } 2082: 2083: 2084: void BootEncryption::CheckEncryptionSetupResult () 2085: { 1.1.1.7 root 2086: CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT); 1.1 root 2087: } 2088: 2089: 1.1.1.6 root 2090: void BootEncryption::Install (bool hiddenSystem) 1.1 root 2091: { 2092: BootEncryptionStatus encStatus = GetStatus(); 2093: if (encStatus.DriveMounted) 2094: throw ParameterIncorrect (SRC_POS); 2095: 2096: try 2097: { 1.1.1.6 root 2098: InstallBootLoader (false, hiddenSystem); 2099: 2100: if (!hiddenSystem) 2101: InstallVolumeHeader (); 2102: 2103: RegisterBootDriver (hiddenSystem); 1.1 root 2104: } 2105: catch (Exception &) 2106: { 2107: try 2108: { 2109: RestoreSystemLoader (); 2110: } 2111: catch (Exception &e) 2112: { 2113: e.Show (ParentWindow); 2114: } 2115: 2116: throw; 2117: } 2118: } 2119: 2120: 1.1.1.6 root 2121: void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5) 2122: { 2123: BootEncryptionStatus encStatus = GetStatus(); 2124: if (encStatus.DriveMounted) 2125: throw ParameterIncorrect (SRC_POS); 2126: 2127: CheckRequirements(); 2128: BackupSystemLoader(); 2129: 2130: SelectedEncryptionAlgorithmId = ea; 2131: } 2132: 2133: 1.1 root 2134: void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath) 2135: { 2136: BootEncryptionStatus encStatus = GetStatus(); 2137: if (encStatus.DriveMounted) 2138: throw ParameterIncorrect (SRC_POS); 2139: 2140: CheckRequirements (); 2141: 2142: SystemDriveConfiguration config = GetSystemDriveConfiguration(); 1.1.1.7 root 2143: 2144: // Some chipset drivers may prevent access to the last sector of the drive 2145: if (!systemPartitionOnly) 2146: { 2147: DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber); 2148: Buffer sector (geometry.BytesPerSector); 2149: 2150: Device device (config.DevicePath); 2151: 2152: try 2153: { 2154: device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector); 2155: device.Read (sector.Ptr(), sector.Size()); 2156: } 2157: catch (SystemException &e) 2158: { 2159: if (e.ErrorCode != ERROR_CRC) 2160: { 2161: e.Show (ParentWindow); 2162: Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS"); 2163: throw UserAbort (SRC_POS); 2164: } 2165: } 2166: } 2167: 1.1 root 2168: BackupSystemLoader (); 2169: 2170: uint64 volumeSize; 2171: uint64 encryptedAreaStart; 2172: 2173: if (systemPartitionOnly) 2174: { 2175: volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart; 2176: encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart; 2177: } 2178: else 2179: { 2180: volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE; 2181: encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE; 2182: } 2183: 1.1.1.3 root 2184: SelectedEncryptionAlgorithmId = ea; 1.1 root 2185: CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5); 2186: 2187: if (!rescueIsoImagePath.empty()) 2188: CreateRescueIsoImage (true, rescueIsoImagePath); 2189: } 2190: 1.1.1.6 root 2191: bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) 1.1.1.5 root 2192: { 2193: if (!IsAdmin() && IsUacSupported()) 1.1.1.6 root 2194: return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2195: 1.1.1.6 root 2196: return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false; 1.1.1.5 root 2197: } 2198: 1.1.1.8 root 2199: void BootEncryption::RestrictPagingFilesToSystemPartition () 2200: { 2201: char pagingFiles[128]; 2202: strncpy (pagingFiles, "X:\\pagefile.sys 0 0", sizeof (pagingFiles)); 2203: pagingFiles[0] = GetWindowsDirectory()[0]; 2204: 2205: throw_sys_if (!WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", pagingFiles, strlen (pagingFiles) + 2)); 2206: } 1.1.1.5 root 2207: 2208: void BootEncryption::WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value) 2209: { 2210: if (!IsAdmin() && IsUacSupported()) 2211: { 2212: Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value); 2213: return; 2214: } 2215: 2216: throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value)); 2217: } 2218: 1.1.1.10 root 2219: uint32 BootEncryption::ReadDriverConfigurationFlags () 2220: { 2221: DWORD configMap; 2222: 2223: if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap)) 2224: configMap = 0; 2225: 2226: return configMap; 2227: } 2228: 2229: void BootEncryption::SetDriverConfigurationFlag (uint32 flag, bool state) 2230: { 2231: DWORD configMap = ReadDriverConfigurationFlags(); 2232: 2233: if (state) 2234: configMap |= flag; 2235: else 2236: configMap &= ~flag; 2237: 2238: WriteLocalMachineRegistryDwordValue ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap); 2239: } 1.1.1.5 root 2240: 1.1.1.8 root 2241: void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors) 1.1 root 2242: { 2243: BootEncryptionStatus encStatus = GetStatus(); 2244: 2245: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2246: throw ParameterIncorrect (SRC_POS); 2247: 2248: BootEncryptionSetupRequest request; 2249: ZeroMemory (&request, sizeof (request)); 2250: 2251: request.SetupMode = SetupDecryption; 1.1.1.8 root 2252: request.DiscardUnreadableEncryptedSectors = discardUnreadableEncryptedSectors; 1.1 root 2253: 2254: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2255: } 2256: 1.1.1.6 root 2257: void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors) 1.1 root 2258: { 2259: BootEncryptionStatus encStatus = GetStatus(); 2260: 2261: if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress) 2262: throw ParameterIncorrect (SRC_POS); 2263: 2264: BootEncryptionSetupRequest request; 2265: ZeroMemory (&request, sizeof (request)); 2266: 2267: request.SetupMode = SetupEncryption; 2268: request.WipeAlgorithm = wipeAlgorithm; 1.1.1.6 root 2269: request.ZeroUnreadableSectors = zeroUnreadableSectors; 1.1 root 2270: 2271: CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0); 2272: } 2273: 1.1.1.10 root 2274: void BootEncryption::CopyFileAdmin (const string &sourceFile, const string &destinationFile) 2275: { 2276: if (!IsAdmin()) 2277: { 2278: if (!IsUacSupported()) 2279: { 2280: SetLastError (ERROR_ACCESS_DENIED); 2281: throw SystemException(); 2282: } 2283: else 2284: Elevator::CopyFile (sourceFile, destinationFile); 2285: } 2286: else 2287: throw_sys_if (!::CopyFile (sourceFile.c_str(), destinationFile.c_str(), FALSE)); 2288: } 2289: 2290: void BootEncryption::DeleteFileAdmin (const string &file) 2291: { 2292: if (!IsAdmin() && IsUacSupported()) 2293: Elevator::DeleteFile (file); 2294: else 2295: throw_sys_if (!::DeleteFile (file.c_str())); 2296: } 2297: 1.1.1.2 root 2298: #endif // !SETUP 1.1 root 2299: 1.1.1.6 root 2300: 2301: void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data) 2302: { 2303: WriteBootDriveSectorRequest request; 2304: request.Offset.QuadPart = offset; 2305: memcpy (request.Data, data, sizeof (request.Data)); 2306: 2307: CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0); 2308: } 2309: 2310: 2311: void BootEncryption::RegisterBootDriver (bool hiddenSystem) 1.1.1.3 root 2312: { 2313: SetDriverServiceStartType (SERVICE_BOOT_START); 2314: 2315: try 2316: { 1.1.1.5 root 2317: RegisterFilterDriver (false, false); 2318: RegisterFilterDriver (false, true); 1.1.1.3 root 2319: } 2320: catch (...) { } 2321: 1.1.1.5 root 2322: RegisterFilterDriver (true, false); 1.1.1.6 root 2323: 2324: if (hiddenSystem) 2325: RegisterFilterDriver (true, true); 1.1.1.3 root 2326: } 2327: 2328: 1.1 root 2329: bool BootEncryption::RestartComputer (void) 2330: { 1.1.1.5 root 2331: return (::RestartComputer() != FALSE); 1.1 root 2332: } 2333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.