Annotation of truecrypt/common/bootencryption.cpp, revision 1.1.1.2

1.1       root        1: /*
                      2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
                      3: 
                      4: Governed by the TrueCrypt License 2.4 the full text of which is contained
                      5: in the file License.txt included in TrueCrypt binary and source code
                      6: distribution packages.
                      7: */
                      8: 
                      9: #include "Tcdefs.h"
                     10: #include "Platform/Finally.h"
                     11: #include "Platform/ForEach.h"
                     12: #include <Setupapi.h>
                     13: #include <devguid.h>
                     14: #include <io.h>
                     15: #include <shlobj.h>
                     16: #include <atlbase.h>
                     17: #include "BootEncryption.h"
                     18: #include "Boot/Windows/BootCommon.h"
                     19: #include "Common/Resource.h"
                     20: #include "Crc.h"
                     21: #include "Crypto.h"
                     22: #include "Dlgcode.h"
                     23: #include "Endian.h"
                     24: #include "Random.h"
                     25: #include "Registry.h"
                     26: #include "Volumes.h"
                     27: 
                     28: #ifdef VOLFORMAT
                     29: #include "Format/FormatCom.h"
                     30: #elif defined (TCMOUNT)
                     31: #include "Mount/MainCom.h"
                     32: #endif
                     33: 
                     34: namespace TrueCrypt
                     35: {
                     36: #if !defined (SETUP)
                     37: 
                     38:        class Elevator
                     39:        {
                     40:        public:
                     41:                static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
                     42:                {
                     43:                        Elevate();
                     44: 
                     45:                        CComBSTR inputBstr;
                     46:                        if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK)
                     47:                                throw ParameterIncorrect (SRC_POS);
                     48: 
                     49:                        CComBSTR outputBstr;
                     50:                        if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK)
                     51:                                throw ParameterIncorrect (SRC_POS);
                     52: 
                     53:                        DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr);
                     54:                        if (result != ERROR_SUCCESS)
                     55:                        {
                     56:                                SetLastError (result);
                     57:                                throw SystemException();
                     58:                        }
                     59:                }
                     60: 
                     61:                static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone)
                     62:                {
                     63:                        Elevate();
                     64: 
                     65:                        CComBSTR bufferBstr;
                     66:                        if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK)
                     67:                                throw ParameterIncorrect (SRC_POS);
                     68:                        DWORD result = ElevatedComInstance->ReadWriteFile (write, device, CComBSTR (filePath.c_str()), &bufferBstr, offset, size, sizeDone);
                     69: 
                     70:                        if (result != ERROR_SUCCESS)
                     71:                        {
                     72:                                SetLastError (result);
                     73:                                throw SystemException();
                     74:                        }
                     75: 
                     76:                        if (!write)
                     77:                                memcpy (buffer, (BYTE *) bufferBstr.m_str, size);
                     78:                }
                     79: 
                     80:                static void RegisterFilterDriver (bool registerDriver)
                     81:                {
                     82:                        Elevate();
                     83: 
                     84:                        DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE);
                     85:                        if (result != ERROR_SUCCESS)
                     86:                        {
                     87:                                SetLastError (result);
                     88:                                throw SystemException();
                     89:                        }
                     90:                }
                     91: 
                     92:                static void Release ()
                     93:                {
                     94:                        if (ElevatedComInstance)
                     95:                        {
                     96:                                ElevatedComInstance->Release();
                     97:                                ElevatedComInstance = nullptr;
                     98:                                CoUninitialize ();
                     99:                        }
                    100:                }
                    101: 
                    102:                static void SetDriverServiceStartType (DWORD startType)
                    103:                {
                    104:                        Elevate();
                    105: 
                    106:                        DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType);
                    107:                        if (result != ERROR_SUCCESS)
                    108:                        {
                    109:                                SetLastError (result);
                    110:                                throw SystemException();
                    111:                        }
                    112:                }
                    113: 
                    114:        protected:
                    115:                static void Elevate ()
                    116:                {
                    117:                        if (IsAdmin())
                    118:                        {
                    119:                                SetLastError (ERROR_ACCESS_DENIED);
                    120:                                throw SystemException();
                    121:                        }
                    122: 
                    123:                        if (!ElevatedComInstance)
                    124:                        {
                    125:                                CoInitialize (NULL);
                    126:                                ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg);
                    127:                        }
                    128:                }
                    129:                
                    130: #if defined (TCMOUNT)
                    131:                static ITrueCryptMainCom *ElevatedComInstance;
                    132: #elif defined (VOLFORMAT)
                    133:                static ITrueCryptFormatCom *ElevatedComInstance;
                    134: #endif
                    135:        };
                    136: 
                    137: #if defined (TCMOUNT)
                    138:        ITrueCryptMainCom *Elevator::ElevatedComInstance;
                    139: #elif defined (VOLFORMAT)
                    140:        ITrueCryptFormatCom *Elevator::ElevatedComInstance;
                    141: #endif
                    142: 
                    143: #else // SETUP
                    144:        
                    145:        class Elevator
                    146:        {
                    147:        public:
                    148:                static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); }
                    149:                static void ReadWriteFile (BOOL write, BOOL device, const string &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); }
                    150:                static void RegisterFilterDriver (bool registerDriver) { throw ParameterIncorrect (SRC_POS); }
                    151:                static void Release () { }
                    152:                static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); }
                    153:        };
                    154: 
                    155: #endif // SETUP
                    156: 
                    157: 
                    158:        File::File (string path, bool readOnly, bool create) : Elevated (false), FileOpen (false)
                    159:        {
                    160:                Handle = CreateFile (path.c_str(),
                    161:                        readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA,
                    162:                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING,
                    163:                        FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
                    164: 
                    165:                try
                    166:                {
                    167:                        throw_sys_if (Handle == INVALID_HANDLE_VALUE);
                    168:                }
                    169:                catch (SystemException &)
                    170:                {
                    171:                        if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
                    172:                                Elevated = true;
                    173:                        else
                    174:                                throw;
                    175:                }
                    176: 
                    177:                FileOpen = true;
                    178:                FilePointerPosition = 0;
                    179:                IsDevice = false;
                    180:                Path = path;
                    181:        }
                    182: 
                    183:        void File::Close ()
                    184:        {
                    185:                if (FileOpen)
                    186:                {
                    187:                        if (!Elevated)
                    188:                                CloseHandle (Handle);
                    189: 
                    190:                        FileOpen = false;
                    191:                }
                    192:        }
                    193: 
                    194:        DWORD File::Read (byte *buffer, DWORD size)
                    195:        {
                    196:                DWORD bytesRead;
                    197: 
                    198:                if (Elevated)
                    199:                {
                    200:                        DWORD bytesRead;
                    201: 
                    202:                        Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead);
                    203:                        FilePointerPosition += bytesRead;
                    204:                        return bytesRead;
                    205:                }
                    206: 
                    207:                throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL));
                    208:                return bytesRead;
                    209:        }
                    210: 
                    211:        void File::SeekAt (int64 position)
                    212:        {
                    213:                if (Elevated)
                    214:                {
                    215:                        FilePointerPosition = position;
                    216:                }
                    217:                else
                    218:                {
                    219:                        LARGE_INTEGER pos;
                    220:                        pos.QuadPart = position;
                    221:                        throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN));
                    222:                }
                    223:        }
                    224: 
                    225:        void File::Write (byte *buffer, DWORD size)
                    226:        {
                    227:                DWORD bytesWritten;
                    228:                
                    229:                if (Elevated)
                    230:                {
                    231:                        Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten);
                    232:                        FilePointerPosition += bytesWritten;
                    233:                        throw_sys_if (bytesWritten != size);
                    234:                }
                    235:                else
                    236:                {
                    237:                        throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size);
                    238:                }
                    239:        }
                    240: 
                    241:        void Show (HWND parent, const string &str)
                    242:        {
                    243:                MessageBox (parent, str.c_str(), NULL, 0);
                    244:        }
                    245: 
                    246: 
                    247:        Device::Device (string path, bool readOnly)
                    248:        {
                    249:                 FileOpen = false;
                    250:                 Elevated = false;
                    251: 
                    252:                Handle = CreateFile ((string ("\\\\.\\") + path).c_str(),
                    253:                        readOnly ? FILE_READ_DATA : FILE_READ_DATA | FILE_WRITE_DATA,
                    254:                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                    255:                        FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
                    256: 
                    257:                try
                    258:                {
                    259:                        throw_sys_if (Handle == INVALID_HANDLE_VALUE);
                    260:                }
                    261:                catch (SystemException &)
                    262:                {
                    263:                        if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
                    264:                                Elevated = true;
                    265:                        else
                    266:                                throw;
                    267:                }
                    268: 
                    269:                FileOpen = true;
                    270:                FilePointerPosition = 0;
                    271:                IsDevice = true;
                    272:                Path = path;
                    273:        }
                    274: 
                    275: 
                    276:        BootEncryption::~BootEncryption ()
                    277:        {
                    278:                if (RescueIsoImage)
                    279:                        delete RescueIsoImage;
                    280: 
                    281:                Elevator::Release();
                    282:        }
                    283: 
                    284: 
                    285:        void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
                    286:        {
                    287:                try
                    288:                {
                    289:                        DWORD bytesReturned;
                    290:                        throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL));
                    291:                }
                    292:                catch (SystemException &)
                    293:                {
                    294:                        if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
                    295:                                Elevator::CallDriver (ioctl, input, inputSize, output, outputSize);
                    296:                        else
                    297:                                throw;
                    298:                }
                    299:        }
                    300: 
                    301: 
                    302:        DWORD BootEncryption::GetDriverServiceStartType ()
                    303:        {
                    304:                DWORD startType;
                    305:                throw_sys_if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", &startType));
                    306:                return startType;
                    307:        }
                    308: 
                    309: 
                    310:        void BootEncryption::SetDriverServiceStartType (DWORD startType)
                    311:        {
                    312:                if (!IsAdmin() && IsUacSupported())
                    313:                {
                    314:                        Elevator::SetDriverServiceStartType (startType);
                    315:                        return;
                    316:                }
                    317: 
                    318:                BOOL startOnBoot = (startType == SERVICE_BOOT_START);
                    319: 
                    320:                SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
                    321:                throw_sys_if (!serviceManager);
                    322: 
                    323:                finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); });
                    324: 
                    325:                SC_HANDLE service = OpenService (serviceManager, "truecrypt", SERVICE_CHANGE_CONFIG);
                    326:                throw_sys_if (!service);
                    327: 
                    328:                finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
                    329: 
                    330:                throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
                    331:                        startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL, NULL,
                    332:                        startOnBoot ? "Filter" : NULL,
                    333:                        NULL, NULL, NULL, NULL, NULL));
                    334: 
                    335:                // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER
                    336:                throw_sys_if (!WriteLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "Start", startType));
                    337:        }
                    338: 
                    339: 
                    340:        void BootEncryption::ProbeRealSystemDriveSize ()
                    341:        {
                    342:                if (RealSystemDriveSizeValid)
                    343:                        return;
                    344: 
                    345:                GetSystemDriveConfiguration();
                    346: 
                    347:                ProbeRealDriveSizeRequest request;
                    348:                _snwprintf (request.DeviceName, array_capacity (request.DeviceName), L"%hs", DriveConfig.DrivePartition.DevicePath.c_str());
                    349:                
                    350:                CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request));
                    351:                DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize;
                    352: 
                    353:                RealSystemDriveSizeValid = TRUE;
                    354:        }
                    355: 
                    356: 
                    357:        PartitionList BootEncryption::GetDrivePartitions (int driveNumber)
                    358:        {
                    359:                PartitionList partList;
                    360: 
                    361:                for (int partNumber = 0; partNumber < 64; ++partNumber)
                    362:                {
                    363:                        stringstream partPath;
                    364:                        partPath << "\\Device\\Harddisk" << driveNumber << "\\Partition" << partNumber;
                    365: 
                    366:                        DISK_PARTITION_INFO_STRUCT diskPartInfo;
                    367:                        _snwprintf (diskPartInfo.deviceName, array_capacity (diskPartInfo.deviceName), L"%hs", partPath.str().c_str());
                    368: 
                    369:                        try
                    370:                        {
                    371:                                CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo));
                    372:                        }
                    373:                        catch (...)
                    374:                        {
                    375:                                continue;
                    376:                        }
                    377: 
                    378:                        Partition part;
                    379:                        part.DevicePath = partPath.str();
                    380:                        part.Number = partNumber;
                    381:                        part.Info = diskPartInfo.partInfo;
                    382:                        part.IsGPT = diskPartInfo.IsGPT;
                    383: 
                    384:                        // Mount point
                    385:                        wstringstream ws;
                    386:                        ws << partPath.str().c_str();
                    387:                        int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
                    388: 
                    389:                        if (driveNumber >= 0)
                    390:                        {
                    391:                                part.MountPoint += (char) (driveNumber + 'A');
                    392:                                part.MountPoint += ":";
                    393:                        }
                    394:                        partList.push_back (part);
                    395:                }
                    396: 
                    397:                return partList;
                    398:        }
                    399:        
                    400: 
                    401:        DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber)
                    402:        {
                    403:                stringstream devName;
                    404:                devName << "\\Device\\Harddisk" << driveNumber << "\\Partition0";
                    405: 
                    406:                DISK_GEOMETRY geometry;
                    407:                throw_sys_if (!::GetDriveGeometry ((char *) devName.str().c_str(), &geometry));
                    408:                return geometry;
                    409:        }
                    410: 
                    411:        
                    412:        string BootEncryption::GetWindowsDirectory ()
                    413:        {
                    414:                char buf[MAX_PATH];
                    415:                if (GetSystemDirectory (buf, sizeof (buf)) > 0)
                    416:                        return string (buf);
                    417: 
                    418:                return string();
                    419:        }
                    420:        
                    421: 
                    422:        uint16 BootEncryption::GetInstalledBootLoaderVersion ()
                    423:        {
                    424:                uint16 version;
                    425:                CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version));
                    426:                return version;
                    427:        }
                    428: 
                    429: 
                    430:        BootEncryptionStatus BootEncryption::GetStatus ()
                    431:        {
                    432:                /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */
                    433: 
                    434:                BootEncryptionStatus status;
                    435:                CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status));
                    436:                return status;
                    437:        }
                    438: 
                    439: 
                    440:        void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties)
                    441:        {
                    442:                if (properties == NULL)
                    443:                        throw ParameterIncorrect (SRC_POS);
                    444: 
                    445:                CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties));
                    446:        }
                    447: 
                    448: 
1.1.1.2 ! root      449:        bool BootEncryption::SystemDriveContainsPartitionType (byte type)
        !           450:        {
        !           451:                Device device (GetSystemDriveConfiguration().DevicePath, true);
        !           452: 
        !           453:                byte mbrBuf[SECTOR_SIZE];
        !           454:                device.SeekAt (0);
        !           455:                device.Read (mbrBuf, sizeof (mbrBuf));
        !           456: 
        !           457:                MBR *mbr = reinterpret_cast <MBR *> (mbrBuf);
        !           458:                if (mbr->Signature != 0xaa55)
        !           459:                        throw ParameterIncorrect (SRC_POS);
        !           460: 
        !           461:                for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i)
        !           462:                {
        !           463:                        if (mbr->Partitions[i].Type == type)
        !           464:                                return true;
        !           465:                }
        !           466: 
        !           467:                return false;
        !           468:        }
        !           469: 
        !           470: 
        !           471:        bool BootEncryption::SystemDriveContainsExtendedPartition ()
        !           472:        {
        !           473:                return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED);
        !           474:        }
        !           475: 
        !           476: 
        !           477:        bool BootEncryption::SystemDriveIsDynamic ()
        !           478:        {
        !           479:                return SystemDriveContainsPartitionType (PARTITION_LDM);
        !           480:        }
        !           481: 
        !           482: 
1.1       root      483:        SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration ()
                    484:        {
                    485:                if (DriveConfigValid)
                    486:                        return DriveConfig;
                    487: 
                    488:                SystemDriveConfiguration config;
                    489: 
                    490:                string winDir = GetWindowsDirectory();
                    491: 
                    492:                // Scan all drives
                    493:                for (int driveNumber = 0; driveNumber < 32; ++driveNumber)
                    494:                {
                    495:                        bool windowsFound = false;
                    496:                        config.SystemLoaderPresent = false;
                    497: 
                    498:                        PartitionList partitions = GetDrivePartitions (driveNumber);
                    499:                        foreach (const Partition &part, partitions)
                    500:                        {
                    501:                                if (_access ((part.MountPoint + "\\bootmgr").c_str(), 0) == 0 || _access ((part.MountPoint + "\\ntldr").c_str(), 0) == 0)
                    502:                                        config.SystemLoaderPresent = true;
                    503: 
                    504:                                if (!windowsFound && !part.MountPoint.empty() && winDir.find (part.MountPoint) == 0)
                    505:                                {
                    506:                                        config.SystemPartition = part;
                    507:                                        windowsFound = true;
                    508:                                }
                    509:                        }
                    510: 
                    511:                        if (windowsFound)
                    512:                        {
                    513:                                config.DriveNumber = driveNumber;
                    514: 
                    515:                                stringstream ss;
                    516:                                ss << "PhysicalDrive" << driveNumber;
                    517:                                config.DevicePath = ss.str();
                    518: 
                    519:                                config.DrivePartition = partitions.front();
                    520:                                partitions.pop_front();
                    521:                                config.Partitions = partitions;
                    522: 
                    523:                                config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull;
                    524:                                config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart;
                    525: 
                    526:                                foreach (const Partition &part, config.Partitions)
                    527:                                {
                    528:                                        if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace)
                    529:                                                config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart;
                    530: 
                    531:                                        config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart;
                    532:                                }
                    533: 
                    534:                                DriveConfig = config;
                    535:                                DriveConfigValid = TRUE;
                    536:                                return DriveConfig;
                    537:                        }
                    538:                }
                    539: 
                    540:                throw ParameterIncorrect (SRC_POS);
                    541:        }
                    542: 
                    543: 
                    544:        bool BootEncryption::SystemPartitionCoversWholeDrive ()
                    545:        {
                    546:                SystemDriveConfiguration config = GetSystemDriveConfiguration();
                    547: 
                    548:                return config.Partitions.size() == 1
1.1.1.2 ! root      549:                        && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * 1024 * 1024;
1.1       root      550:        }
                    551: 
                    552: 
                    553:        void BootEncryption::InstallBootLoader ()
                    554:        {
                    555:                Device device (GetSystemDriveConfiguration().DevicePath);
                    556:                DWORD size;
                    557: 
                    558:                // MBR
                    559:                byte *bootSecImg = MapResource ("BIN", IDR_BOOT_SECTOR, &size);
                    560:                if (!bootSecImg || size != SECTOR_SIZE)
                    561:                        throw ParameterIncorrect (SRC_POS);
                    562: 
                    563:                byte bootSecBuf[SECTOR_SIZE];
                    564: 
                    565:                device.SeekAt (0);
                    566:                device.Read (bootSecBuf, sizeof (bootSecBuf));
                    567: 
                    568:                memcpy (bootSecBuf, bootSecImg, TC_MAX_MBR_BOOT_CODE_SIZE);
                    569: 
                    570:                device.SeekAt (0);
                    571:                device.Write (bootSecBuf, size);
                    572: 
                    573:                byte bootSecVerificationBuf[SECTOR_SIZE];
                    574:                device.SeekAt (0);
                    575:                device.Read (bootSecVerificationBuf, size);
                    576: 
                    577:                if (memcmp (bootSecBuf, bootSecVerificationBuf, size) != 0)
                    578:                        throw ErrorException ("ERROR_MBR_PROTECTED");
                    579: 
                    580:                // Boot loader
                    581:                byte bootLoaderBuf[TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET - SECTOR_SIZE];
                    582:                byte *bootLoader = MapResource ("BIN", IDR_BOOT_LOADER, &size);
                    583: 
                    584:                if (!bootLoader || size > sizeof (bootLoaderBuf))
                    585:                        throw ParameterIncorrect (SRC_POS);
                    586: 
                    587:                ZeroMemory (bootLoaderBuf, sizeof (bootLoaderBuf));
                    588:                memcpy (bootLoaderBuf, bootLoader, size);
                    589: 
                    590:                device.SeekAt (SECTOR_SIZE);
                    591:                device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
                    592:        }
                    593: 
                    594: 
                    595:        string BootEncryption::GetSystemLoaderBackupPath ()
                    596:        {
                    597:                char pathBuf[MAX_PATH];
                    598: 
                    599:                throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf)));
                    600:                
                    601:                string path = string (pathBuf) + "\\" TC_APP_NAME;
                    602:                CreateDirectory (path.c_str(), NULL);
                    603: 
                    604:                return path + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME;
                    605:        }
                    606: 
1.1.1.2 ! root      607: #ifndef SETUP
1.1       root      608:        void BootEncryption::CreateRescueIsoImage (bool initialSetup, const string &isoImagePath)
                    609:        {
                    610:                BootEncryptionStatus encStatus = GetStatus();
                    611:                if (encStatus.SetupInProgress)
                    612:                        throw ParameterIncorrect (SRC_POS);
                    613: 
                    614:                Buffer imageBuf (RescueIsoImageSize);
                    615:                
                    616:                byte *image = imageBuf.Ptr();
                    617:                memset (image, 0, RescueIsoImageSize);
                    618: 
                    619:                // Primary volume descriptor
1.1.1.2 ! root      620:                strcpy ((char *)image + 0x8000, "\001CD001\001");
        !           621:                strcpy ((char *)image + 0x7fff + 41, "TrueCrypt Rescue Disk           ");
        !           622:                *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048;
        !           623:                *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048);
        !           624:                image[0x7fff + 121] = 1;
        !           625:                image[0x7fff + 124] = 1;
        !           626:                image[0x7fff + 125] = 1;
        !           627:                image[0x7fff + 128] = 1;
        !           628:                image[0x7fff + 130] = 8;
        !           629:                image[0x7fff + 131] = 8;
        !           630: 
        !           631:                image[0x7fff + 133] = 10;
        !           632:                image[0x7fff + 140] = 10;
        !           633:                image[0x7fff + 141] = 0x14;
        !           634:                image[0x7fff + 157] = 0x22;
        !           635:                image[0x7fff + 159] = 0x18;
1.1       root      636: 
                    637:                // Boot record volume descriptor
                    638:                strcpy ((char *)image + 0x8801, "CD001\001EL TORITO SPECIFICATION");
                    639:                image[0x8800 + 0x47] = 0x19;
                    640: 
1.1.1.2 ! root      641:                // Volume descriptor set terminator
        !           642:                strcpy ((char *)image + 0x9000, "\377CD001\001");
        !           643: 
        !           644:                // Path table
        !           645:                image[0xA000 + 0] = 1;
        !           646:                image[0xA000 + 2] = 0x18;
        !           647:                image[0xA000 + 6] = 1;
        !           648: 
        !           649:                // Root directory
        !           650:                image[0xc000 + 0] = 0x22;
        !           651:                image[0xc000 + 2] = 0x18;
        !           652:                image[0xc000 + 9] = 0x18;
        !           653:                image[0xc000 + 11] = 0x08;
        !           654:                image[0xc000 + 16] = 0x08;
        !           655:                image[0xc000 + 25] = 0x02;
        !           656:                image[0xc000 + 28] = 0x01;
        !           657:                image[0xc000 + 31] = 0x01;
        !           658:                image[0xc000 + 32] = 0x01;
        !           659:                image[0xc000 + 34] = 0x22;
        !           660:                image[0xc000 + 36] = 0x18;
        !           661:                image[0xc000 + 43] = 0x18;
        !           662:                image[0xc000 + 45] = 0x08;
        !           663:                image[0xc000 + 50] = 0x08;
        !           664:                image[0xc000 + 59] = 0x02;
        !           665:                image[0xc000 + 62] = 0x01;
        !           666:                *(uint32 *) (image + 0xc000 + 65) = 0x010101;
        !           667: 
1.1       root      668:                // Validation entry
                    669:                image[0xc800] = 1;
1.1.1.2 ! root      670:                int offset = 0xc800 + 0x1c;
1.1       root      671:                image[offset++] = 0xaa;
                    672:                image[offset++] = 0x55;
                    673:                image[offset++] = 0x55;
                    674:                image[offset] = 0xaa;
                    675: 
                    676:                // Initial entry
                    677:                offset = 0xc820;
                    678:                image[offset++] = 0x88;
                    679:                image[offset++] = 2;
                    680:                image[0xc820 + 6] = 1;
                    681:                image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR;
                    682: 
                    683:                // TrueCrypt Boot Loader
                    684:                DWORD size;
                    685:                byte *bootSecResourceImg = MapResource ("BIN", IDR_BOOT_SECTOR, &size);
                    686:                if (!bootSecResourceImg || size != SECTOR_SIZE)
                    687:                        throw ParameterIncorrect (SRC_POS);
                    688: 
                    689:                byte bootSecImg[SECTOR_SIZE];
                    690:                memcpy (bootSecImg, bootSecResourceImg, sizeof (bootSecImg));
                    691: 
                    692:                bootSecImg[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK;
                    693:                memcpy (image + TC_CD_BOOTSECTOR_OFFSET, bootSecImg, SECTOR_SIZE);
                    694: 
                    695:                byte *bootLoader = MapResource ("BIN", IDR_BOOT_LOADER, &size);
                    696:                if (!bootLoader)
                    697:                        throw ParameterIncorrect (SRC_POS);
                    698: 
                    699:                memcpy (image + TC_CD_BOOTSECTOR_OFFSET + SECTOR_SIZE, bootLoader, size);
                    700:                
                    701:                // Volume header
                    702:                if (initialSetup)
                    703:                {
                    704:                        if (!RescueVolumeHeaderValid)
                    705:                                throw ParameterIncorrect (SRC_POS);
                    706: 
                    707:                        memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, HEADER_SIZE);
                    708:                }
                    709:                else
                    710:                {
                    711:                        Device bootDevice (GetSystemDriveConfiguration().DevicePath, true);
                    712:                        bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
                    713:                        bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, HEADER_SIZE);
                    714:                }
                    715: 
                    716:                // Original system loader
                    717:                try
                    718:                {
                    719:                        File sysBakFile (GetSystemLoaderBackupPath(), true);
                    720:                        sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE);
                    721:                        
                    722:                        image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER;
                    723:                }
                    724:                catch (Exception &e)
                    725:                {
                    726:                        e.Show (ParentWindow);
                    727:                        Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK");
                    728:                }
                    729:                
                    730:                RescueIsoImage = new byte[RescueIsoImageSize];
                    731:                if (!RescueIsoImage)
                    732:                        throw bad_alloc();
                    733:                memcpy (RescueIsoImage, image, RescueIsoImageSize);
                    734: 
                    735:                if (!isoImagePath.empty())
                    736:                {
                    737:                        File isoFile (isoImagePath, false, true);
                    738:                        isoFile.Write (image, RescueIsoImageSize);
                    739:                }
                    740:        }
1.1.1.2 ! root      741: #endif
1.1       root      742: 
                    743:        bool BootEncryption::VerifyRescueDisk ()
                    744:        {
                    745:                if (!RescueIsoImage)
                    746:                        throw ParameterIncorrect (SRC_POS);
                    747: 
                    748:                for (char drive = 'Z'; drive >= 'D'; --drive)
                    749:                {
                    750:                        try
                    751:                        {
                    752:                                string path = "X:";
                    753:                                path[0] = drive;
                    754: 
                    755:                                Device driveDevice (path, true);
                    756:                                size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048;
                    757:                                Buffer buffer ((verifiedSectorCount + 1) * 2048);
                    758: 
                    759:                                DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size());
                    760:                                if (bytesRead != buffer.Size())
                    761:                                        continue;
                    762: 
                    763:                                if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0)
                    764:                                        return true;
                    765:                        }
                    766:                        catch (...) { }
                    767:                }
                    768: 
                    769:                return false;
                    770:        }
                    771: 
                    772: 
                    773: #ifndef SETUP
                    774: 
                    775:        void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5)
                    776:        {
                    777:                PCRYPTO_INFO cryptoInfo = NULL;
                    778:                
                    779:                throw_sys_if (Randinit () != 0);
                    780:                throw_sys_if (VolumeWriteHeader (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, 0, &cryptoInfo,
                    781:                        volumeSize, 0, encryptedAreaStart, 0, FALSE) != 0);
                    782: 
                    783:                finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); });
                    784: 
                    785:                // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize)
                    786:                memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader));
                    787:                VolumeReadHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo);
                    788: 
                    789:                DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
                    790: 
                    791:                if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
                    792:                        throw ParameterIncorrect (SRC_POS);
                    793: 
                    794:                byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH;
                    795:                mputInt64 (fieldPos, volumeSize);
                    796:                
                    797:                EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
                    798: 
                    799:                VolumeHeaderValid = true;
                    800:                RescueVolumeHeaderValid = true;
                    801:        }
                    802: 
                    803: 
                    804:        void BootEncryption::InstallVolumeHeader ()
                    805:        {
                    806:                if (!VolumeHeaderValid)
                    807:                        throw ParameterIncorrect (SRC_POS);
                    808: 
                    809:                Device device (GetSystemDriveConfiguration().DevicePath);
                    810: 
                    811:                device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
                    812:                device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
                    813:        }
                    814: 
                    815: 
                    816:        // For synchronous operations use AbortSetupWait()
                    817:        void BootEncryption::AbortSetup ()
                    818:        {
                    819:                CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
                    820:        }
                    821: 
                    822: 
                    823:        // For asynchronous operations use AbortSetup()
                    824:        void BootEncryption::AbortSetupWait ()
                    825:        {
                    826:                CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
                    827: 
                    828:                BootEncryptionStatus encStatus = GetStatus();
                    829: 
                    830:                while (encStatus.SetupInProgress)
                    831:                {
                    832:                        Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
                    833:                        encStatus = GetStatus();
                    834:                }
                    835:        }
                    836: 
                    837: 
                    838:        void BootEncryption::BackupSystemLoader ()
                    839:        {
                    840:                Device device (GetSystemDriveConfiguration().DevicePath, true);
                    841:        
                    842:                byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];
                    843: 
                    844:                device.SeekAt (0);
                    845:                device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));
                    846: 
                    847:                // Prevent TrueCrypt loader from being backed up
                    848:                for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
                    849:                {
                    850:                        if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
                    851:                        {
                    852:                                if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO)
                    853:                                        throw UserAbort (SRC_POS);
                    854:                                return;
                    855:                        }
                    856:                }
                    857: 
                    858:                File backupFile (GetSystemLoaderBackupPath(), false, true);
                    859:                backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
                    860:        }
                    861: 
                    862: 
                    863:        void BootEncryption::RestoreSystemLoader ()
                    864:        {
                    865:                byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];
                    866: 
                    867:                File backupFile (GetSystemLoaderBackupPath(), true);
                    868:                
                    869:                if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
                    870:                        throw ParameterIncorrect (SRC_POS);
                    871: 
                    872:                Device device (GetSystemDriveConfiguration().DevicePath);
                    873:                device.SeekAt (0);
                    874:                device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
                    875:        }
                    876: 
                    877: 
                    878:        void BootEncryption::RegisterFilterDriver (bool registerDriver)
                    879:        {
                    880:                if (!IsAdmin() && IsUacSupported())
                    881:                {
                    882:                        Elevator::RegisterFilterDriver (registerDriver);
                    883:                        return;
                    884:                }
                    885: 
                    886:                HKEY classRegKey = SetupDiOpenClassRegKey (&GUID_DEVCLASS_DISKDRIVE, KEY_READ | KEY_WRITE);
                    887:                throw_sys_if (classRegKey == INVALID_HANDLE_VALUE);
                    888:                finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); });
                    889: 
1.1.1.2 ! root      890:                if (registerDriver && nCurrentOS == WIN_VISTA_OR_LATER)
1.1       root      891:                {
1.1.1.2 ! root      892:                        // Attaching to the device stack after PartMgr on Vista causes all write IRPs sent to the lower device object to fail
        !           893:                        // with STATUS_ACCESS_DENIED. Therefore, our filter is placed in front of others already registered.
1.1       root      894:                        size_t strSize = strlen ("truecrypt") + 1;
                    895:                        byte regKeyBuf[65536];
                    896:                        DWORD size = sizeof (regKeyBuf) - strSize;
                    897: 
                    898:                        // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
                    899:                        strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf));
                    900: 
                    901:                        if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
                    902:                                size = 1;
                    903: 
                    904:                        throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS);
                    905:                }
                    906:                else
                    907:                {
                    908:                        char tempPath[MAX_PATH];
                    909:                        GetTempPath (sizeof (tempPath), tempPath);
                    910:                        string infFileName = string (tempPath) + "\\truecrypt_filter.inf";
                    911: 
                    912:                        finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); });
                    913:                        File infFile (infFileName, false, true);
                    914: 
1.1.1.2 ! root      915:                        string infTxt = "[truecrypt]\r\n" + string (registerDriver ? "Add" : "Del") + "Reg=truecrypt_reg\r\n\r\n"
        !           916:                                "[truecrypt_reg]\r\nHKR,,\"UpperFilters\",0x0001" + string (registerDriver ? "0008" : "8002") + ",\"truecrypt\"\r\n";
1.1       root      917: 
                    918:                        infFile.Write ((byte *) infTxt.c_str(), infTxt.size());
                    919:                        infFile.Close();
                    920: 
                    921:                        HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
                    922:                        throw_sys_if (hInf == INVALID_HANDLE_VALUE);
                    923:                        finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); });
                    924: 
                    925:                        throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL));
                    926:                }
                    927:        }
                    928: 
                    929: 
                    930:        void BootEncryption::CheckRequirements ()
                    931:        {
                    932:                if (nCurrentOS == WIN_2000)
                    933:                        throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS");
                    934: 
                    935:                if (IsNonInstallMode())
                    936:                        throw ErrorException ("FEATURE_REQUIRES_INSTALLATION");
                    937: 
                    938:                SystemDriveConfiguration config = GetSystemDriveConfiguration ();
                    939: 
                    940:                if (config.SystemPartition.IsGPT)
                    941:                        throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED");
                    942: 
                    943:                if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
                    944:                        throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER");
                    945: 
                    946:                DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
                    947: 
                    948:                if (geometry.BytesPerSector != SECTOR_SIZE)
                    949:                        throw ErrorException ("LARGE_SECTOR_UNSUPPORTED");
                    950: 
                    951:                if (!config.SystemLoaderPresent)
                    952:                        throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
                    953:        }
                    954: 
                    955: 
                    956:        void BootEncryption::Deinstall ()
                    957:        {
                    958:                BootEncryptionStatus encStatus = GetStatus();
                    959: 
                    960:                if (encStatus.DriveEncrypted || encStatus.DriveMounted)
                    961:                        throw ParameterIncorrect (SRC_POS);
                    962: 
                    963:                SystemDriveConfiguration config = GetSystemDriveConfiguration ();
                    964: 
                    965:                if (encStatus.VolumeHeaderPresent)
                    966:                {
                    967:                        // Verify CRC of header salt
                    968:                        Device device (config.DevicePath, true);
                    969:                        byte header[SECTOR_SIZE];
                    970: 
                    971:                        device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
                    972:                        device.Read (header, sizeof (header));
                    973: 
                    974:                        if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
                    975:                                throw ParameterIncorrect (SRC_POS);
                    976:                }
                    977: 
                    978:                RegisterFilterDriver (false);
                    979:                SetDriverServiceStartType (SERVICE_SYSTEM_START);
                    980: 
                    981:                try
                    982:                {
                    983:                        RestoreSystemLoader ();
                    984:                }
                    985:                catch (Exception &e)
                    986:                {
                    987:                        e.Show (ParentWindow);
                    988:                        throw ErrorException ("SYS_LOADER_RESTORE_FAILED");
                    989:                }
                    990:        }
                    991: 
                    992: 
                    993:        int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5)
                    994:        {
                    995:                if (GetStatus().SetupInProgress)
                    996:                        throw ParameterIncorrect (SRC_POS);
                    997: 
                    998:                SystemDriveConfiguration config = GetSystemDriveConfiguration ();
                    999: 
                   1000:                char header[HEADER_SIZE];
                   1001:                Device device (config.DevicePath);
                   1002: 
                   1003:                // Only one algorithm is currently supported
                   1004:                if (pkcs5 != 0)
                   1005:                        throw ParameterIncorrect (SRC_POS);
                   1006: 
                   1007:                device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
                   1008:                device.Read ((byte *) header, sizeof (header));
                   1009: 
                   1010:                PCRYPTO_INFO cryptoInfo = NULL;
                   1011:                
                   1012:                int status = VolumeReadHeader (TRUE, header, oldPassword, &cryptoInfo, NULL);
                   1013:                finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
                   1014: 
                   1015:                if (status != 0)
                   1016:                {
                   1017:                        handleError (ParentWindow, status);
                   1018:                        return status;
                   1019:                }
                   1020: 
                   1021:                // Change the PKCS-5 PRF if requested by user
                   1022:                if (pkcs5 != 0)
                   1023:                        cryptoInfo->pkcs5 = pkcs5;
                   1024: 
                   1025:                throw_sys_if (Randinit () != 0);
                   1026: 
                   1027:                /* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 
                   1028:                techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
                   1029:                to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
                   1030:                times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
                   1031:                impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
                   1032:                valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
                   1033:                recommends. During each pass we will write a valid working header. Each pass will use the same master
                   1034:                key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
                   1035:                item that will be different for each pass will be the salt. This is sufficient to cause each "version"
                   1036:                of the header to differ substantially and in a random manner from the versions written during the
                   1037:                other passes. */
                   1038: 
                   1039:                bool headerUpdated = false;
                   1040:                int result = ERR_SUCCESS;
                   1041: 
                   1042:                try
                   1043:                {
                   1044:                        for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
                   1045:                        {
                   1046:                                PCRYPTO_INFO tmpCryptoInfo = NULL;
                   1047: 
                   1048:                                status = VolumeWriteHeader (TRUE,
                   1049:                                        header,
                   1050:                                        cryptoInfo->ea,
                   1051:                                        cryptoInfo->mode,
                   1052:                                        newPassword,
                   1053:                                        cryptoInfo->pkcs5,
                   1054:                                        (char *) cryptoInfo->master_keydata,
                   1055:                                        cryptoInfo->volume_creation_time,
                   1056:                                        &tmpCryptoInfo,
                   1057:                                        cryptoInfo->VolumeSize.Value,
                   1058:                                        cryptoInfo->hiddenVolumeSize,
                   1059:                                        cryptoInfo->EncryptedAreaStart.Value,
                   1060:                                        cryptoInfo->EncryptedAreaLength.Value,
                   1061:                                        wipePass < PRAND_DISK_WIPE_PASSES - 1);
                   1062: 
                   1063:                                if (tmpCryptoInfo)
                   1064:                                        crypto_close (tmpCryptoInfo);
                   1065: 
                   1066:                                if (status != 0)
                   1067:                                {
                   1068:                                        handleError (ParentWindow, status);
                   1069:                                        return status;
                   1070:                                }
                   1071: 
                   1072:                                device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
                   1073:                                device.Write ((byte *) header, sizeof (header));
                   1074:                                headerUpdated = true;
                   1075:                        }
                   1076:                }
                   1077:                catch (Exception &e)
                   1078:                {
                   1079:                        e.Show (ParentWindow);
                   1080:                        result = ERR_OS_ERROR;
                   1081:                }
                   1082: 
                   1083:                if (headerUpdated)
                   1084:                {
                   1085:                        ReopenBootVolumeHeaderRequest reopenRequest;
                   1086:                        reopenRequest.VolumePassword = *newPassword;
                   1087:                        finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
                   1088: 
                   1089:                        CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
                   1090:                }
                   1091: 
                   1092:                return result;
                   1093:        }
                   1094: 
                   1095: 
                   1096:        void BootEncryption::CheckEncryptionSetupResult ()
                   1097:        {
                   1098:                CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
                   1099:        }
                   1100: 
                   1101: 
                   1102:        void BootEncryption::Install ()
                   1103:        {
                   1104:                BootEncryptionStatus encStatus = GetStatus();
                   1105:                if (encStatus.DriveMounted)
                   1106:                        throw ParameterIncorrect (SRC_POS);
                   1107: 
                   1108:                try
                   1109:                {
                   1110:                        InstallBootLoader ();
                   1111:                        InstallVolumeHeader ();
                   1112: 
                   1113:                        SetDriverServiceStartType (SERVICE_BOOT_START);
                   1114: 
                   1115:                        try
                   1116:                        {
                   1117:                                RegisterFilterDriver (false);
                   1118:                        }
                   1119:                        catch (...) { }
                   1120: 
                   1121:                        RegisterFilterDriver (true);
                   1122:                }
                   1123:                catch (Exception &)
                   1124:                {
                   1125:                        try
                   1126:                        {
                   1127:                                RestoreSystemLoader ();
                   1128:                        }
                   1129:                        catch (Exception &e)
                   1130:                        {
                   1131:                                e.Show (ParentWindow);
                   1132:                        }
                   1133: 
                   1134:                        throw;
                   1135:                }
                   1136:        }
                   1137: 
                   1138: 
                   1139:        void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath)
                   1140:        {
                   1141:                if (!systemPartitionOnly && !RealSystemDriveSizeValid)
                   1142:                        ProbeRealSystemDriveSize();
                   1143: 
                   1144:                BootEncryptionStatus encStatus = GetStatus();
                   1145:                if (encStatus.DriveMounted)
                   1146:                        throw ParameterIncorrect (SRC_POS);
                   1147: 
                   1148:                CheckRequirements ();
                   1149: 
                   1150:                SystemDriveConfiguration config = GetSystemDriveConfiguration();
                   1151:                BackupSystemLoader ();
                   1152: 
                   1153:                uint64 volumeSize;
                   1154:                uint64 encryptedAreaStart;
                   1155: 
                   1156:                if (systemPartitionOnly)
                   1157:                {
                   1158:                        volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
                   1159:                        encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
                   1160:                }
                   1161:                else
                   1162:                {
                   1163:                        volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
                   1164:                        encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
                   1165:                }
                   1166: 
                   1167:                CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5);
                   1168:                
                   1169:                if (!rescueIsoImagePath.empty())
                   1170:                        CreateRescueIsoImage (true, rescueIsoImagePath);
                   1171:        }
                   1172:        
                   1173: 
                   1174:        void BootEncryption::StartDecryption ()
                   1175:        {
                   1176:                BootEncryptionStatus encStatus = GetStatus();
                   1177: 
                   1178:                if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
                   1179:                        throw ParameterIncorrect (SRC_POS);
                   1180: 
                   1181:                BootEncryptionSetupRequest request;
                   1182:                ZeroMemory (&request, sizeof (request));
                   1183:                
                   1184:                request.SetupMode = SetupDecryption;
                   1185: 
                   1186:                CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
                   1187:        }
                   1188: 
                   1189: 
                   1190:        void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm)
                   1191:        {
                   1192:                BootEncryptionStatus encStatus = GetStatus();
                   1193: 
                   1194:                if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
                   1195:                        throw ParameterIncorrect (SRC_POS);
                   1196: 
                   1197:                BootEncryptionSetupRequest request;
                   1198:                ZeroMemory (&request, sizeof (request));
                   1199:                
                   1200:                request.SetupMode = SetupEncryption;
                   1201:                request.WipeAlgorithm = wipeAlgorithm;
                   1202: 
                   1203:                CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
                   1204:        }
                   1205: 
1.1.1.2 ! root     1206: #endif // !SETUP
1.1       root     1207: 
                   1208:        bool BootEncryption::RestartComputer (void)
                   1209:        {
                   1210:                TOKEN_PRIVILEGES tokenPrivil; 
                   1211:                HANDLE hTkn; 
                   1212: 
                   1213:                if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn))
                   1214:                {
                   1215:                        return false; 
                   1216:                }
                   1217: 
                   1218:                LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid); 
                   1219:                tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
                   1220:                tokenPrivil.PrivilegeCount = 1;    
                   1221: 
                   1222:                AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0); 
                   1223:                if (GetLastError() != ERROR_SUCCESS) 
                   1224:                        return false; 
                   1225: 
                   1226:                if (!ExitWindowsEx (EWX_REBOOT | EWX_FORCE, 
                   1227:                        SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) 
                   1228:                        return false; 
                   1229: 
                   1230:                return true;
                   1231:        }
                   1232: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.