⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootencryption.cpp

📁 功能强大的开源加密软件。使用最新ieee-p1619标准
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

		if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
			throw ParameterIncorrect (SRC_POS);

		byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH;
		mputInt64 (fieldPos, volumeSize);
		
		EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

		VolumeHeaderValid = true;
		RescueVolumeHeaderValid = true;
	}


	void BootEncryption::InstallVolumeHeader ()
	{
		if (!VolumeHeaderValid)
			throw ParameterIncorrect (SRC_POS);

		Device device (GetSystemDriveConfiguration().DevicePath);

		device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
		device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
	}


	// For synchronous operations use AbortSetupWait()
	void BootEncryption::AbortSetup ()
	{
		CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
	}


	// For asynchronous operations use AbortSetup()
	void BootEncryption::AbortSetupWait ()
	{
		CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);

		BootEncryptionStatus encStatus = GetStatus();

		while (encStatus.SetupInProgress)
		{
			Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
			encStatus = GetStatus();
		}
	}


	void BootEncryption::BackupSystemLoader ()
	{
		Device device (GetSystemDriveConfiguration().DevicePath, true);
	
		byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];

		device.SeekAt (0);
		device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));

		// Prevent TrueCrypt loader from being backed up
		for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
		{
			if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
			{
				if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO)
					throw UserAbort (SRC_POS);
				return;
			}
		}

		File backupFile (GetSystemLoaderBackupPath(), false, true);
		backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
	}


	void BootEncryption::RestoreSystemLoader ()
	{
		byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];

		File backupFile (GetSystemLoaderBackupPath(), true);
		
		if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
			throw ParameterIncorrect (SRC_POS);

		Device device (GetSystemDriveConfiguration().DevicePath);
		device.SeekAt (0);
		device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
	}

#endif // SETUP

	void BootEncryption::RegisterFilterDriver (bool registerDriver)
	{
		if (!IsAdmin() && IsUacSupported())
		{
			Elevator::RegisterFilterDriver (registerDriver);
			return;
		}

		HKEY classRegKey = SetupDiOpenClassRegKey (&GUID_DEVCLASS_DISKDRIVE, KEY_READ | KEY_WRITE);
		throw_sys_if (classRegKey == INVALID_HANDLE_VALUE);
		finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); });

		if (registerDriver && nCurrentOS == WIN_VISTA_OR_LATER)
		{
			// Attaching to the device stack after PartMgr on Vista causes all write IRPs sent to the lower device object to fail
			// with STATUS_ACCESS_DENIED. Therefore, our filter is placed in front of others already registered.
			size_t strSize = strlen ("truecrypt") + 1;
			byte regKeyBuf[65536];
			DWORD size = sizeof (regKeyBuf) - strSize;

			// SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
			strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf));

			if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
				size = 1;

			throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS);
		}
		else
		{
			char tempPath[MAX_PATH];
			GetTempPath (sizeof (tempPath), tempPath);
			string infFileName = string (tempPath) + "\\truecrypt_filter.inf";

			finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); });
			File infFile (infFileName, false, true);

			string infTxt = "[truecrypt]\r\n" + string (registerDriver ? "Add" : "Del") + "Reg=truecrypt_reg\r\n\r\n"
				"[truecrypt_reg]\r\nHKR,,\"UpperFilters\",0x0001" + string (registerDriver ? "0008" : "8002") + ",\"truecrypt\"\r\n";

			infFile.Write ((byte *) infTxt.c_str(), infTxt.size());
			infFile.Close();

			HINF hInf = SetupOpenInfFile (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
			throw_sys_if (hInf == INVALID_HANDLE_VALUE);
			finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); });

			throw_sys_if (!SetupInstallFromInfSection (ParentWindow, hInf, "truecrypt", SPINST_REGISTRY, classRegKey, NULL, 0, NULL, NULL, NULL, NULL));
		}
	}

#ifndef SETUP

	void BootEncryption::CheckRequirements ()
	{
		if (nCurrentOS == WIN_2000)
			throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS");

		if (IsNonInstallMode())
			throw ErrorException ("FEATURE_REQUIRES_INSTALLATION");

		SystemDriveConfiguration config = GetSystemDriveConfiguration ();

		if (config.SystemPartition.IsGPT)
			throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED");

		if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
			throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER");

		DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);

		if (geometry.BytesPerSector != SECTOR_SIZE)
			throw ErrorException ("LARGE_SECTOR_UNSUPPORTED");

		if (!config.SystemLoaderPresent)
			throw ErrorException ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR");
	}


	void BootEncryption::Deinstall ()
	{
		BootEncryptionStatus encStatus = GetStatus();

		if (encStatus.DriveEncrypted || encStatus.DriveMounted)
			throw ParameterIncorrect (SRC_POS);

		SystemDriveConfiguration config = GetSystemDriveConfiguration ();

		if (encStatus.VolumeHeaderPresent)
		{
			// Verify CRC of header salt
			Device device (config.DevicePath, true);
			byte header[SECTOR_SIZE];

			device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
			device.Read (header, sizeof (header));

			if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
				throw ParameterIncorrect (SRC_POS);
		}

		RegisterFilterDriver (false);
		SetDriverServiceStartType (SERVICE_SYSTEM_START);

		try
		{
			RestoreSystemLoader ();
		}
		catch (Exception &e)
		{
			e.Show (ParentWindow);
			throw ErrorException ("SYS_LOADER_RESTORE_FAILED");
		}
	}


	int BootEncryption::ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5)
	{
		if (GetStatus().SetupInProgress)
			throw ParameterIncorrect (SRC_POS);

		SystemDriveConfiguration config = GetSystemDriveConfiguration ();

		char header[HEADER_SIZE];
		Device device (config.DevicePath);

		// Only one algorithm is currently supported
		if (pkcs5 != 0)
			throw ParameterIncorrect (SRC_POS);

		device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
		device.Read ((byte *) header, sizeof (header));

		PCRYPTO_INFO cryptoInfo = NULL;
		
		int status = VolumeReadHeader (TRUE, header, oldPassword, &cryptoInfo, NULL);
		finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });

		if (status != 0)
		{
			handleError (ParentWindow, status);
			return status;
		}

		// Change the PKCS-5 PRF if requested by user
		if (pkcs5 != 0)
			cryptoInfo->pkcs5 = pkcs5;

		throw_sys_if (Randinit () != 0);

		/* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 
		techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
		to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
		times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
		impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
		valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
		recommends. During each pass we will write a valid working header. Each pass will use the same master
		key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
		item that will be different for each pass will be the salt. This is sufficient to cause each "version"
		of the header to differ substantially and in a random manner from the versions written during the
		other passes. */

		bool headerUpdated = false;
		int result = ERR_SUCCESS;

		try
		{
			for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
			{
				PCRYPTO_INFO tmpCryptoInfo = NULL;

				status = VolumeWriteHeader (TRUE,
					header,
					cryptoInfo->ea,
					cryptoInfo->mode,
					newPassword,
					cryptoInfo->pkcs5,
					(char *) cryptoInfo->master_keydata,
					cryptoInfo->volume_creation_time,
					&tmpCryptoInfo,
					cryptoInfo->VolumeSize.Value,
					cryptoInfo->hiddenVolumeSize,
					cryptoInfo->EncryptedAreaStart.Value,
					cryptoInfo->EncryptedAreaLength.Value,
					wipePass < PRAND_DISK_WIPE_PASSES - 1);

				if (tmpCryptoInfo)
					crypto_close (tmpCryptoInfo);

				if (status != 0)
				{
					handleError (ParentWindow, status);
					return status;
				}

				device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
				device.Write ((byte *) header, sizeof (header));
				headerUpdated = true;
			}
		}
		catch (Exception &e)
		{
			e.Show (ParentWindow);
			result = ERR_OS_ERROR;
		}

		if (headerUpdated)
		{
			ReopenBootVolumeHeaderRequest reopenRequest;
			reopenRequest.VolumePassword = *newPassword;
			finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });

			CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
		}

		return result;
	}


	void BootEncryption::CheckEncryptionSetupResult ()
	{
		CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
	}


	void BootEncryption::Install ()
	{
		BootEncryptionStatus encStatus = GetStatus();
		if (encStatus.DriveMounted)
			throw ParameterIncorrect (SRC_POS);

		try
		{
			InstallBootLoader ();
			InstallVolumeHeader ();
			RegisterBootDriver ();

			// Prevent system log errors caused by rejecting crash dumps
			WriteLocalMachineRegistryDword ("System\\CurrentControlSet\\Control\\CrashControl", "CrashDumpEnabled", 0);
		}
		catch (Exception &)
		{
			try
			{
				RestoreSystemLoader ();
			}
			catch (Exception &e)
			{
				e.Show (ParentWindow);
			}

			throw;
		}
	}


	void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath)
	{
		if (!systemPartitionOnly && !RealSystemDriveSizeValid)
			ProbeRealSystemDriveSize();

		BootEncryptionStatus encStatus = GetStatus();
		if (encStatus.DriveMounted)
			throw ParameterIncorrect (SRC_POS);

		CheckRequirements ();

		SystemDriveConfiguration config = GetSystemDriveConfiguration();
		BackupSystemLoader ();

		uint64 volumeSize;
		uint64 encryptedAreaStart;

		if (systemPartitionOnly)
		{
			volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
			encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
		}
		else
		{
			volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
			encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
		}

		SelectedEncryptionAlgorithmId = ea;
		CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5);
		
		if (!rescueIsoImagePath.empty())
			CreateRescueIsoImage (true, rescueIsoImagePath);
	}
	

	void BootEncryption::StartDecryption ()
	{
		BootEncryptionStatus encStatus = GetStatus();

		if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
			throw ParameterIncorrect (SRC_POS);

		BootEncryptionSetupRequest request;
		ZeroMemory (&request, sizeof (request));
		
		request.SetupMode = SetupDecryption;

		CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
	}


	void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm)
	{
		BootEncryptionStatus encStatus = GetStatus();

		if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
			throw ParameterIncorrect (SRC_POS);

		BootEncryptionSetupRequest request;
		ZeroMemory (&request, sizeof (request));
		
		request.SetupMode = SetupEncryption;
		request.WipeAlgorithm = wipeAlgorithm;

		CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
	}

#endif // !SETUP

	void BootEncryption::RegisterBootDriver (void)
	{
		SetDriverServiceStartType (SERVICE_BOOT_START);

		try
		{
			RegisterFilterDriver (false);
		}
		catch (...) { }

		RegisterFilterDriver (true);
	}


	bool BootEncryption::RestartComputer (void)
	{
		TOKEN_PRIVILEGES tokenPrivil; 
		HANDLE hTkn; 

		if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn))
		{
			return false; 
		}

		LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid); 
		tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
		tokenPrivil.PrivilegeCount = 1;    

		AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0); 
		if (GetLastError() != ERROR_SUCCESS) 
			return false; 

		if (!ExitWindowsEx (EWX_REBOOT | EWX_FORCE, 
			SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) 
			return false; 

		return true;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -