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