VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkavsrf <kavsrf@gmail.com>2016-12-04 13:40:51 +0300
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2016-12-26 00:00:02 +0100
commitcd6df44d6f0e31bb81595f69691443cf1e4b21cf (patch)
treea2a181e1e616be19c01e045bef2e44f1e1b1bf11 /src
parenta7f8548e2fa592123b87e47095649e5c46702ab5 (diff)
downloadVeraCrypt-cd6df44d6f0e31bb81595f69691443cf1e4b21cf.tar.gz
VeraCrypt-cd6df44d6f0e31bb81595f69691443cf1e4b21cf.zip
Driver with support of hidden OS
Signed-off-by: kavsrf <kavsrf@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/Driver/DriveFilter.c156
-rw-r--r--src/Driver/EncryptedIoQueue.c59
-rw-r--r--src/Driver/EncryptedIoQueue.h2
3 files changed, 191 insertions, 26 deletions
diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c
index 66f49816..b8aad224 100644
--- a/src/Driver/DriveFilter.c
+++ b/src/Driver/DriveFilter.c
@@ -33,6 +33,10 @@ static BOOL DeviceFilterActive = FALSE;
33 33
34BOOL BootArgsValid = FALSE; 34BOOL BootArgsValid = FALSE;
35BootArguments BootArgs; 35BootArguments BootArgs;
36byte* BootSecRegionData = NULL;
37uint32 BootSecRegionSize = 0;
38uint32 BootPkcs5;
39
36static uint64 BootLoaderArgsPtr; 40static uint64 BootLoaderArgsPtr;
37static BOOL BootDriveSignatureValid = FALSE; 41static BOOL BootDriveSignatureValid = FALSE;
38 42
@@ -76,10 +80,11 @@ NTSTATUS LoadBootArguments ()
76 NTSTATUS status = STATUS_UNSUCCESSFUL; 80 NTSTATUS status = STATUS_UNSUCCESSFUL;
77 PHYSICAL_ADDRESS bootArgsAddr; 81 PHYSICAL_ADDRESS bootArgsAddr;
78 byte *mappedBootArgs; 82 byte *mappedBootArgs;
83 byte *mappedCryptoInfo = NULL;
79 uint16 bootLoaderArgsIndex; 84 uint16 bootLoaderArgsIndex;
80 85
81 KeInitializeMutex (&MountMutex, 0); 86 KeInitializeMutex (&MountMutex, 0);
82 87// __debugbreak();
83 for (bootLoaderArgsIndex = 0; 88 for (bootLoaderArgsIndex = 0;
84 bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS; 89 bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS;
85 ++bootLoaderArgsIndex) 90 ++bootLoaderArgsIndex)
@@ -126,22 +131,61 @@ NTSTATUS LoadBootArguments ()
126 Dump ("BootDriveSignature = %x\n", BootArgs.BootDriveSignature); 131 Dump ("BootDriveSignature = %x\n", BootArgs.BootDriveSignature);
127 Dump ("BootArgumentsCrc32 = %x\n", BootArgs.BootArgumentsCrc32); 132 Dump ("BootArgumentsCrc32 = %x\n", BootArgs.BootArgumentsCrc32);
128 133
129 if (CacheBootPassword && BootArgs.BootPassword.Length > 0)
130 {
131 int pim = CacheBootPim? (int) (BootArgs.Flags >> 16) : 0;
132 AddPasswordToCache (&BootArgs.BootPassword, pim);
133 }
134
135 // clear fingerprint 134 // clear fingerprint
136 burn (BootLoaderFingerprint, sizeof (BootLoaderFingerprint)); 135 burn (BootLoaderFingerprint, sizeof (BootLoaderFingerprint));
136 MmUnmapIoSpace (mappedBootArgs, sizeof (BootArguments));
137 137
138 if (BootArgs.CryptoInfoLength > 0)
139 {
140 PHYSICAL_ADDRESS cryptoInfoAddress;
141 cryptoInfoAddress.QuadPart = BootLoaderArgsPtr + BootArgs.CryptoInfoOffset;
142 Dump ("CryptoInfo memory %x %d\n", cryptoInfoAddress.LowPart, BootArgs.CryptoInfoLength);
143
144 mappedCryptoInfo = MmMapIoSpace (cryptoInfoAddress, BootArgs.CryptoInfoLength, MmCached);
145 if (mappedCryptoInfo)
146 {
147 /* Get the parameters used for booting to speed up driver startup and avoid testing irrelevant PRFs */
148 BOOT_CRYPTO_HEADER* pBootCryptoInfo = (BOOT_CRYPTO_HEADER*) mappedCryptoInfo;
149 BootPkcs5 = pBootCryptoInfo->pkcs5;
150
151 BootSecRegionData = NULL;
152 BootSecRegionSize = 0;
153
154 if(BootArgs.CryptoInfoLength > (sizeof(BOOT_CRYPTO_HEADER) + sizeof(SECREGION_BOOT_PARAMS)) ) {
155 uint32 crc;
156 PHYSICAL_ADDRESS SecRegionAddress;
157 SECREGION_BOOT_PARAMS* SecRegionParams = (SECREGION_BOOT_PARAMS*) (mappedCryptoInfo + sizeof(BOOT_CRYPTO_HEADER) + 2);
158 byte *secRegionData = NULL;
159
160 SecRegionAddress.QuadPart = SecRegionParams->Ptr;
161 Dump ("SecRegion memory 0x%x %d\n", SecRegionAddress.LowPart, SecRegionParams->Size);
162
163 if( (SecRegionParams->Ptr != 0) && (SecRegionParams->Size > 0)) {
164 crc = GetCrc32((byte*)SecRegionParams, 12);
165 if(crc == SecRegionParams->Crc) {
166 Dump ("SecRegion crc ok\n");
167 secRegionData = MmMapIoSpace (SecRegionAddress, SecRegionParams->Size, MmCached);
168 BootSecRegionData = TCalloc (SecRegionParams->Size);
169 if(BootSecRegionData != NULL) {
170 BootSecRegionSize = SecRegionParams->Size;
171 memcpy(BootSecRegionData, secRegionData, SecRegionParams->Size);
172 }
173 burn (secRegionData, SecRegionParams->Size);
174 MmUnmapIoSpace (secRegionData, SecRegionParams->Size);
175 }
176 // Erase boot loader scheduled keys
177 burn (mappedCryptoInfo, BootArgs.CryptoInfoLength);
178 MmUnmapIoSpace (mappedCryptoInfo, BootArgs.CryptoInfoLength);
179 }
180 }
181 }
182 }
138 status = STATUS_SUCCESS; 183 status = STATUS_SUCCESS;
139 } 184 }
185 } else {
186 MmUnmapIoSpace (mappedBootArgs, sizeof (BootArguments));
140 } 187 }
141
142 MmUnmapIoSpace (mappedBootArgs, sizeof (BootArguments));
143 } 188 }
144
145 return status; 189 return status;
146} 190}
147 191
@@ -327,30 +371,55 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
327 Dump ("MountDrive pdo=%p\n", Extension->Pdo); 371 Dump ("MountDrive pdo=%p\n", Extension->Pdo);
328 ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); 372 ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
329 373
330 // Check boot drive signature first (header CRC search could fail if a user restored the header to a non-boot drive) 374 if (BootSecRegionData != NULL && BootSecRegionSize >= 1024) {
331 if (BootDriveSignatureValid)
332 {
333 byte mbr[TC_SECTOR_SIZE_BIOS]; 375 byte mbr[TC_SECTOR_SIZE_BIOS];
334 376 DCS_DISK_ENTRY_LIST* DeList = (DCS_DISK_ENTRY_LIST*)(BootSecRegionData + 512);
335 offset.QuadPart = 0; 377 offset.QuadPart = 0;
336 status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS); 378 status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS);
337 379
338 if (NT_SUCCESS (status) && BootArgs.BootDriveSignature != *(uint32 *) (mbr + 0x1b8)) 380 if (NT_SUCCESS (status) && DeList->DE[DE_IDX_DISKID].DiskId.MbrID != *(uint32 *) (mbr + 0x1b8))
339 return STATUS_UNSUCCESSFUL; 381 return STATUS_UNSUCCESSFUL;
340 }
341 382
342 header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); 383 offset.QuadPart = 512;
343 if (!header) 384 status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS);
344 return STATUS_INSUFFICIENT_RESOURCES; 385 if (NT_SUCCESS (status) && memcmp(&DeList->DE[DE_IDX_DISKID].DiskId.GptID, mbr + 0x38, sizeof(DCS_GUID)) != 0)
386 return STATUS_UNSUCCESSFUL;
345 387
346 offset.QuadPart = hiddenVolume ? hiddenHeaderOffset : TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; 388 header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
347 Dump ("Reading volume header at %I64u\n", offset.QuadPart); 389 if (!header)
390 return STATUS_INSUFFICIENT_RESOURCES;
391 memcpy(header, BootSecRegionData, 512);
392 // Set extra data for the disk
393 Extension->Queue.SecRegionData = BootSecRegionData;
394 Extension->Queue.SecRegionSize = BootSecRegionSize;
395 } else {
396 // Check boot drive signature first (header CRC search could fail if a user restored the header to a non-boot drive)
397 if (BootDriveSignatureValid)
398 {
399 byte mbr[TC_SECTOR_SIZE_BIOS];
348 400
349 status = TCReadDevice (Extension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); 401 offset.QuadPart = 0;
350 if (!NT_SUCCESS (status)) 402 status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS);
351 { 403
352 Dump ("TCReadDevice error %x\n", status); 404 if (NT_SUCCESS (status) && BootArgs.BootDriveSignature != *(uint32 *) (mbr + 0x1b8))
353 goto ret; 405 return STATUS_UNSUCCESSFUL;
406 }
407
408 header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
409 if (!header)
410 return STATUS_INSUFFICIENT_RESOURCES;
411
412 offset.QuadPart = hiddenVolume ? hiddenHeaderOffset : TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
413 Dump ("Reading volume header at %I64u\n", offset.QuadPart);
414
415 status = TCReadDevice (Extension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
416 if (!NT_SUCCESS (status))
417 {
418 Dump ("TCReadDevice error %x\n", status);
419 goto ret;
420 }
421 Extension->Queue.SecRegionData = NULL;
422 Extension->Queue.SecRegionSize = 0;
354 } 423 }
355 424
356 if (headerSaltCrc32) 425 if (headerSaltCrc32)
@@ -469,6 +538,41 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password,
469 BootDriveFound = Extension->BootDrive = Extension->DriveMounted = Extension->VolumeHeaderPresent = TRUE; 538 BootDriveFound = Extension->BootDrive = Extension->DriveMounted = Extension->VolumeHeaderPresent = TRUE;
470 BootDriveFilterExtension->MagicNumber = TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER; 539 BootDriveFilterExtension->MagicNumber = TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER;
471 540
541 if (BootSecRegionData != NULL && BootSecRegionSize > 1024) {
542 DCS_DISK_ENTRY_LIST* DeList = (DCS_DISK_ENTRY_LIST*)(BootSecRegionData + 512);
543 uint32 crc;
544 uint32 crcSaved;
545 crcSaved = DeList->CRC32;
546 DeList->CRC32 = 0;
547 crc = GetCrc32((byte*)DeList, 512);
548 if(crc == crcSaved){
549 if(DeList->DE[DE_IDX_PWDCACHE].Type == DE_PwdCache) {
550 uint64 sector = 0;
551 DCS_DEP_PWD_CACHE* pwdCache = (DCS_DEP_PWD_CACHE*)(BootSecRegionData + DeList->DE[DE_IDX_PWDCACHE].Sectors.Offset);
552 DecryptDataUnits((unsigned char*)pwdCache, (UINT64_STRUCT*)&sector, 1, Extension->Queue.CryptoInfo);
553 crcSaved = pwdCache->CRC;
554 pwdCache->CRC = 0;
555 crc = GetCrc32((unsigned char*)pwdCache, 512);
556 if(crcSaved == crc && pwdCache->Count < CACHE_SIZE){
557 uint32 i;
558 for(i = 0; i<pwdCache->Count; ++i){
559 if (CacheBootPassword && pwdCache->Pwd[i].Length > 0) {
560 int pim = CacheBootPim? (int) (pwdCache->Pim[i]) : 0;
561 AddPasswordToCache (&pwdCache->Pwd[i], pim);
562 }
563 }
564 burn(pwdCache, sizeof(*pwdCache));
565 }
566 }
567 }
568 }
569
570 if (CacheBootPassword && BootArgs.BootPassword.Length > 0)
571 {
572 int pim = CacheBootPim? (int) (BootArgs.Flags >> 16) : 0;
573 AddPasswordToCache (&BootArgs.BootPassword, pim);
574 }
575
472 burn (&BootArgs.BootPassword, sizeof (BootArgs.BootPassword)); 576 burn (&BootArgs.BootPassword, sizeof (BootArgs.BootPassword));
473 577
474 { 578 {
diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c
index 029a42f5..7f50ec30 100644
--- a/src/Driver/EncryptedIoQueue.c
+++ b/src/Driver/EncryptedIoQueue.c
@@ -225,6 +225,47 @@ static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, byte *buffer)
225 } 225 }
226} 226}
227 227
228BOOL
229UpdateBuffer(
230 byte* buffer,
231 byte* secRegion,
232 uint64 bufferDiskOffset,
233 uint32 bufferLength,
234 BOOL doUpadte
235 )
236{
237 uint64 intersectStart;
238 uint32 intersectLength;
239 uint32 i;
240 DCS_DISK_ENTRY_LIST *DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512);
241 BOOL updated = FALSE;
242
243 if (secRegion == NULL) return FALSE;
244 for (i = 0; i < DeList->Count; ++i) {
245 if (DeList->DE[i].Type == DE_Sectors) {
246 GetIntersection(
247 bufferDiskOffset, bufferLength,
248 DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1,
249 &intersectStart, &intersectLength
250 );
251 if (intersectLength != 0) {
252 updated = TRUE;
253 if(doUpadte && buffer != NULL) {
254// Dump("Subst data\n");
255 memcpy(
256 buffer + (intersectStart - bufferDiskOffset),
257 secRegion + DeList->DE[i].Sectors.Offset + (intersectStart - DeList->DE[i].Sectors.Start),
258 intersectLength
259 );
260 } else {
261 return TRUE;
262 }
263 }
264 }
265 }
266 return updated;
267}
268
228 269
229static VOID CompletionThreadProc (PVOID threadArg) 270static VOID CompletionThreadProc (PVOID threadArg)
230{ 271{
@@ -260,6 +301,11 @@ static VOID CompletionThreadProc (PVOID threadArg)
260 301
261 DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); 302 DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
262 } 303 }
304// Dump("Read sector %lld count %d\n", request->Offset.QuadPart >> 9, request->Length >> 9);
305 // Update subst sectors
306 if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
307 UpdateBuffer(request->Data, queue->SecRegionData, request->Offset.QuadPart, request->Length, TRUE);
308 }
263 309
264 if (request->CompleteOriginalIrp) 310 if (request->CompleteOriginalIrp)
265 { 311 {
@@ -609,6 +655,10 @@ static VOID MainThreadProc (PVOID threadArg)
609 DecryptDataUnits (buffer + (intersectStart - alignedOffset.QuadPart), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); 655 DecryptDataUnits (buffer + (intersectStart - alignedOffset.QuadPart), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
610 } 656 }
611 } 657 }
658 // Update subst sectors
659 if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
660 UpdateBuffer(buffer, queue->SecRegionData, alignedOffset.QuadPart, alignedLength, TRUE);
661 }
612 662
613 memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength); 663 memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength);
614 } 664 }
@@ -697,6 +747,15 @@ static VOID MainThreadProc (PVOID threadArg)
697 Dump ("Preventing write to boot loader or host protected area\n"); 747 Dump ("Preventing write to boot loader or host protected area\n");
698 CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0); 748 CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
699 continue; 749 continue;
750 }
751 else if (item->Write
752 && (queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)
753 && UpdateBuffer (NULL, queue->SecRegionData, item->OriginalOffset.QuadPart, (uint32)(item->OriginalOffset.QuadPart + item->OriginalLength - 1), FALSE))
754 {
755 // Prevent inappropriately designed software from damaging important data
756 Dump ("Preventing write to the system GPT area\n");
757 CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
758 continue;
700 } 759 }
701 760
702 dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority); 761 dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority);
diff --git a/src/Driver/EncryptedIoQueue.h b/src/Driver/EncryptedIoQueue.h
index ffe71471..fe9365ed 100644
--- a/src/Driver/EncryptedIoQueue.h
+++ b/src/Driver/EncryptedIoQueue.h
@@ -117,6 +117,8 @@ typedef struct
117 LARGE_INTEGER LastPerformanceCounter; 117 LARGE_INTEGER LastPerformanceCounter;
118#endif 118#endif
119 119
120 byte* SecRegionData;
121 SIZE_T SecRegionSize;
120} EncryptedIoQueue; 122} EncryptedIoQueue;
121 123
122 124