VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Format/FormatCom.cpp
blob: aac5ae7e870636924378a2c1ef9a44cb0c23c8d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf
/*
 Derived from source code of TrueCrypt 7.1a, which is
 Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
 by the TrueCrypt License 3.0.

 Modifications and additions to the original source code (contained in this file) 
 and all other portions of this file are Copyright (c) 2013-2015 IDRIX
 and are governed by the Apache License 2.0 the full text of which is
 contained in the file License.txt included in VeraCrypt binary and source
 code distribution packages.
*/

#include <atlcomcli.h>
#include <atlconv.h>
#include <comutil.h>
#include <windows.h>
#include "BaseCom.h"
#include "BootEncryption.h"
#include "Dlgcode.h"
#include "Format.h"
#include "Progress.h"
#include "TcFormat.h"
#include "FormatCom.h"
#include "FormatCom_h.h"
#include "FormatCom_i.c"

using namespace VeraCrypt;

static volatile LONG ObjectCount = 0;

class TrueCryptFormatCom : public ITrueCryptFormatCom
{

public:
	TrueCryptFormatCom (DWORD messageThreadId) : RefCount (0),
		MessageThreadId (messageThreadId),
		CallBack (NULL)
	{
		InterlockedIncrement (&ObjectCount);
	}

	virtual ~TrueCryptFormatCom ()
	{
		if (InterlockedDecrement (&ObjectCount) == 0)
			PostThreadMessage (MessageThreadId, WM_APP, 0, 0);
	}

	virtual ULONG STDMETHODCALLTYPE AddRef ()
	{
		return InterlockedIncrement (&RefCount);
	}

	virtual ULONG STDMETHODCALLTYPE Release ()
	{
		if (!InterlockedDecrement (&RefCount))
		{
			delete this;
			return 0;
		}

		return RefCount;
	}

	virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject)
	{
		if (riid == IID_IUnknown || riid == IID_ITrueCryptFormatCom)
			*ppvObject = this;
		else
		{
			*ppvObject = NULL;
			return E_NOINTERFACE;
		}

		AddRef ();
		return S_OK;
	}
	
	virtual DWORD STDMETHODCALLTYPE CallDriver (DWORD ioctl, BSTR input, BSTR *output)
	{
		return BaseCom::CallDriver (ioctl, input, output);
	}

	virtual DWORD STDMETHODCALLTYPE CopyFile (BSTR sourceFile, BSTR destinationFile)
	{
		return BaseCom::CopyFile (sourceFile, destinationFile);
	}

	virtual DWORD STDMETHODCALLTYPE DeleteFile (BSTR file)
	{
		return BaseCom::DeleteFile (file);
	}

	virtual BOOL STDMETHODCALLTYPE FormatNtfs (int driveNo, int clusterSize)
	{
		return ::FormatNtfs (driveNo, clusterSize);
	}

	virtual int STDMETHODCALLTYPE AnalyzeHiddenVolumeHost (
		LONG_PTR hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters)
	{
		return ::AnalyzeHiddenVolumeHost (
			(HWND) hwndDlg, driveNo, hiddenVolHostSize, realClusterSize, nbrFreeClusters);
	}

	virtual DWORD STDMETHODCALLTYPE ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone)
	{
		return BaseCom::ReadWriteFile (write, device, filePath, bufferBstr, offset, size, sizeDone);
	}

	virtual DWORD STDMETHODCALLTYPE RegisterFilterDriver (BOOL registerDriver, int filterType)
	{
		return BaseCom::RegisterFilterDriver (registerDriver, filterType);
	}

	virtual DWORD STDMETHODCALLTYPE RegisterSystemFavoritesService (BOOL registerService)
	{
		return BaseCom::RegisterSystemFavoritesService (registerService);
	}

	virtual DWORD STDMETHODCALLTYPE SetDriverServiceStartType (DWORD startType)
	{
		return BaseCom::SetDriverServiceStartType (startType);
	}

	virtual BOOL STDMETHODCALLTYPE IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
	{
		return BaseCom::IsPagingFileActive (checkNonWindowsPartitionsOnly);
	}

	virtual DWORD STDMETHODCALLTYPE WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value)
	{
		return BaseCom::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
	}

protected:
	DWORD MessageThreadId;
	LONG RefCount;
	ITrueCryptFormatCom *CallBack;
};


extern "C" BOOL ComServerFormat ()
{
	SetProcessShutdownParameters (0x100, 0);

	TrueCryptFactory<TrueCryptFormatCom> factory (GetCurrentThreadId ());
	DWORD cookie;

	if (IsUacSupported ())
		UacElevated = TRUE;

	if (CoRegisterClassObject (CLSID_TrueCryptFormatCom, (LPUNKNOWN) &factory,
		CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie) != S_OK)
		return FALSE;

	MSG msg;
	while (int r = GetMessageW (&msg, NULL, 0, 0))
	{
		if (r == -1)
			return FALSE;

		TranslateMessage (&msg);
		DispatchMessageW (&msg);

		if (msg.message == WM_APP
			&& ObjectCount < 1
			&& !factory.IsServerLocked ())
			break;
	}
	CoRevokeClassObject (cookie);

	return TRUE;
}


static BOOL ComGetInstance (HWND hWnd, ITrueCryptFormatCom **tcServer)
{
	return ComGetInstanceBase (hWnd, CLSID_TrueCryptFormatCom, IID_ITrueCryptFormatCom, (void **) tcServer);
}


ITrueCryptFormatCom *GetElevatedInstance (HWND parent)
{
	ITrueCryptFormatCom *instance;

	if (!ComGetInstance (parent, &instance))
		throw UserAbort (SRC_POS);

	return instance;
}


extern "C" int UacFormatNtfs (HWND hWnd, int driveNo, int clusterSize)
{
	CComPtr<ITrueCryptFormatCom> tc;
	int r;

	CoInitialize (NULL);

	if (ComGetInstance (hWnd, &tc))
		r = tc->FormatNtfs (driveNo, clusterSize);
	else
		r = 0;

	CoUninitialize ();

	return r;
}


extern "C" int UacAnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHostSize, int *realClusterSize, __int64 *nbrFreeClusters)
{
	CComPtr<ITrueCryptFormatCom> tc;
	int r;

	CoInitialize (NULL);

	if (ComGetInstance (hwndDlg, &tc))
		r = tc->AnalyzeHiddenVolumeHost ((LONG_PTR) hwndDlg, driveNo, hiddenVolHostSize, realClusterSize, nbrFreeClusters);
	else
		r = 0;

	CoUninitialize ();

	return r;
}
alog window).</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Access to a keyfile stored on a security token or smart card is typically protected by PIN codes, which can be entered either using a hardware PIN pad or via the VeraCrypt GUI. It can also be protected by other means, such as fingerprint readers.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> In order to allow VeraCrypt to access a security token or smart card, you need to install a PKCS #11 (2.0 or later) software library for the token or smart card first. Such a library may be supplied with the device or it may be available for download from the website of the vendor or other third parties.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> If your security token or smart card does not contain any file (data object) that you could use as a VeraCrypt keyfile, you can use VeraCrypt to import any file to the token or smart card (if it is supported by the device). To do so, follow these steps:</div> <ol style="text-align:left; margin-top:18px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> <li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"> In the keyfile dialog window, click <em style="text-align:left">Add Token Files</em>. </li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"> If the token or smart card is protected by a PIN, password, or other means (such as a fingerprint reader), authenticate yourself (for example, by entering the PIN using a hardware PIN pad). </li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"> The 'Security Token Keyfile' dialog window should appear. In it, click <em style="text-align:left"> Import Keyfile to Token</em> and then select the file you want to import to the token or smart card. </li></ol> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Note that you can import for example 512-bit keyfiles with random content generated by VeraCrypt (see <em style="text-align:left">Tools &gt; Keyfile Generator</em> below).</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> To close all opened security token sessions, either select <em style="text-align:left"> Tools</em> &gt; <em style="text-align:left">Close All Security Token Sessions</em> or define and use a hotkey combination (<em style="text-align:left">Settings</em> &gt; <em style="text-align:left">Hot Keys &gt; Close All Security Token Sessions</em>).</div> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Keyfile Search Path</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> By adding a folder in the keyfile dialog window (click <em style="text-align:left"> Add Path</em>), you specify a <em style="text-align:left">keyfile search path</em>. All files found in the keyfile search path* will be used as keyfiles except files that have the Hidden file attribute set.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> <strong style="text-align:left"><em style="text-align:left">Important: Note that folders (and files they contain) and hidden files found in a keyfile search path are ignored.</em></strong></div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Keyfile search paths are especially useful if you, for example, store keyfiles on a USB memory stick that you carry with you. You can set the drive letter of the USB memory stick as a default keyfile search path. To do so, select <em style="text-align:left">Settings </em>-&gt; <em style="text-align:left">Default Keyfiles</em>. Then click <br style="text-align:left"> <em style="text-align:left">Add Path</em>, browse to the drive letter assigned to the USB memory stick, and click <em style="text-align:left">OK</em>. Now each time you mount a volume (and if the option <em style="text-align:left">Use keyfiles</em> is checked in the password dialog window), VeraCrypt will scan the path and use all files that it finds on the USB memory stick as keyfiles.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> <strong style="text-align:left"><em style="text-align:left">WARNING: When you add a folder (as opposed to a file) to the list of keyfiles, only the path is remembered, not the filenames! This means e.g. that if you create a new file in the folder or if you copy an additional file to the folder, then all volumes that used keyfiles from the folder will be impossible to mount (until you remove the newly added file from the folder). </em></strong></div> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Empty Password &amp; Keyfile</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> When a keyfile is used, the password may be empty, so the keyfile may become the only item necessary to mount the volume (which we do not recommend). If default keyfiles are set and enabled when mounting a volume, then before prompting for a password, VeraCrypt first automatically attempts to mount using an empty password plus default keyfiles (however, this does not apply to the '<em style="text-align:left">Auto-Mount Devices</em>' function). If you need to set Mount Options (e.g., mount as read-only, protect hidden volume etc.) for a volume being mounted this way, hold down the <em style="text-align:left"> Control </em>(<em style="text-align:left">Ctrl</em>) key while clicking <em style="text-align:left"> Mount </em>(or select <em style="text-align:left">Mount with Options </em>from the <em style="text-align:left">Volumes </em>menu). This will open the <em style="text-align:left"> Mount Options </em>dialog.</div> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Quick Selection</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Keyfiles and keyfile search paths can be quickly selected in the following ways:</div> <ul style="text-align:left; margin-top:18px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> <li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"> Right-click the <em style="text-align:left">Keyfiles</em> button in the password entry dialog window and select one of the menu items. </li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px"> Drag the corresponding file/folder icons to the keyfile dialog window or to the password entry dialog. </li></ul> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Volumes -&gt; Add/Remove Keyfiles to/from Volume</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> This function allows you to re-encrypt a volume header with a header encryption key derived from any number of keyfiles (with or without a password), or no keyfiles at all. Thus, a volume which is possible to mount using only a password can be converted to a volume that require keyfiles (in addition to the password) in order to be possible to mount. Note that the volume header contains the master encryption key with which the volume is encrypted. Therefore, the data stored on the volume will <em style="text-align:left">not</em> be lost after you use this function.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> This function can also be used to change/set volume keyfiles (i.e., to remove some or all keyfiles, and to apply new ones).</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Remark: This function is internally equal to the Password Change function.<br style="text-align:left"> <br style="text-align:left"> When VeraCrypt re-encrypts a volume header, the original volume header is first overwritten 256 times with random data to prevent adversaries from using techniques such as magnetic force microscopy or magnetic force scanning tunneling microscopy [17] to recover the overwritten header (however, see also the chapter <a href="Security%20Requirements%20and%20Precautions.html" style="text-align:left; color:#0080c0; text-decoration:none.html"> Security Requirements and Precautions</a>).</div> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Volumes -&gt; Remove All Keyfiles from Volume</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> This function allows you to re-encrypt a volume header with a header encryption key derived from a password and no keyfiles (so that it can be mounted using only a password, without any keyfiles). Note that the volume header contains the master encryption key with which the volume is encrypted. Therefore, the data stored on the volume will <em style="text-align:left">not</em> be lost after you use this function.</div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Remark: This function is internally equal to the Password Change function.<br style="text-align:left"> <br style="text-align:left"> When VeraCrypt re-encrypts a volume header, the original volume header is first overwritten 256 times with random data to prevent adversaries from using techniques such as magnetic force microscopy or magnetic force scanning tunneling microscopy [17] to recover the overwritten header (however, see also the chapter <a href="Security%20Requirements%20and%20Precautions.html" style="text-align:left; color:#0080c0; text-decoration:none.html"> Security Requirements and Precautions</a>).</div> <p>&nbsp;</p> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Tools &gt; Keyfile Generator</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> You can use this function to generate a file or more with random content, which you can use as a keyfile(s) (recommended). This function uses the VeraCrypt Random Number Generator. Note that, by default, only one key file is generated and the resulting file size is 64 bytes (i.e., 512 bits), which is also the maximum possible VeraCrypt password length. It is also possible to generate multiple files and specify their size (either a fixed value for all of them or let VeraCrypt choose file sizes randomly). In all cases, the file size must be comprised between 64 bytes and 1048576 bytes (which is equal to 1MB, the maximum number of a key file bytes processed by VeraCrypt).</div> <h3 style="text-align:left; font-family:Arial,Helvetica,Verdana,sans-serif; font-weight:bold; margin-top:0px; font-size:13px; margin-bottom:4px"> Settings -&gt; Default Keyfiles</h3> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> Use this function to set default keyfiles and/or default keyfile search paths. This function is particularly useful if you, for example, store keyfiles on a USB memory stick that you carry with you. You can add its drive letter to the default keyfile configuration. To do so, click <em style="text-align:left">Add Path</em>, browse to the drive letter assigned to the USB memory stick, and click <em style="text-align:left">OK</em>. Now each time you mount a volume (and if <em style="text-align:left"> Use keyfiles</em> is checked in the password dialog), VeraCrypt will scan the path and use all files that it finds there as keyfiles.<br style="text-align:left"> <br style="text-align:left"> <strong style="text-align:left"><em style="text-align:left">WARNING: When you add a folder (as opposed to a file) to your default keyfile list, only the path is remembered, not the filenames! This means e.g. that if you create a new file in the folder or if you copy an additional file to the folder, then all volumes that used keyfiles from the folder will be impossible to mount (until you remove the newly added file from the folder). <br style="text-align:left"> <br style="text-align:left"> </em></strong><span style="text-align:left; font-style:italic">IMPORTANT: Note that when you set default keyfiles and/or default keyfile search paths, the filenames and paths are saved unencrypted in the file </span>Default Keyfiles.xml<span style="text-align:left; font-style:italic">. For more information, please see the chapter </span><a href="VeraCrypt%20System%20Files.html" style="text-align:left; color:#0080c0; text-decoration:none">VeraCrypt System Files &amp; Application Data</a><span style="text-align:left; font-style:italic.html">. </span></div> <div style="text-align:left; margin-top:19px; margin-bottom:19px; padding-top:0px; padding-bottom:0px"> <em style="text-align:left"><br style="text-align:left"> </em></div> <hr align="left" size="1" width="189" style="text-align:left; height:0px; border-width:0px 1px 1px; border-style:solid; border-color:#000000"> <p><span style="text-align:left; font-size:10px; line-height:12px">* Found at the time when you are mounting the volume, changing its password, or performing any other operation that involves re-encryption of the volume header.<br style="text-align:left"> ** However, if you use an MP3 file as a keyfile, you must ensure that no program modifies the ID3 tags within the MP3 file (e.g. song title, name of artist, etc.). Otherwise, it will be impossible to mount volumes that use the keyfile.<br style="text-align:left"> </span></p> </div><div class="ClearBoth"></div></body></html>