VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Driver/Ntvol.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Driver/Ntvol.c')
-rw-r--r--src/Driver/Ntvol.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c
index 177c0bf3..68f63f16 100644
--- a/src/Driver/Ntvol.c
+++ b/src/Driver/Ntvol.c
@@ -61,70 +61,72 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
/* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/
BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache;
Extension->pfoDeviceFile = NULL;
Extension->hDeviceFile = NULL;
Extension->bTimeStampValid = FALSE;
/* default value for storage alignment */
Extension->HostMaximumTransferLength = 65536;
Extension->HostMaximumPhysicalPages = 17;
Extension->HostAlignmentMask = 0;
/* default values for non-SSD drives */
Extension->IncursSeekPenalty = TRUE;
Extension->TrimEnabled = FALSE;
Extension->DeviceNumber = (ULONG) -1;
RtlInitUnicodeString (&FullFileName, pwszMountVolume);
InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL);
KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE);
if (Extension->SecurityClientContextValid)
{
ntStatus = SeImpersonateClientEx (&Extension->SecurityClientContext, NULL);
if (!NT_SUCCESS (ntStatus))
goto error;
}
mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE;
+ mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE;
+ mount->VolumeMasterKeyVulnerable = FALSE;
// If we are opening a device, query its size first
if (bRawDevice)
{
PARTITION_INFORMATION pi;
PARTITION_INFORMATION_EX pix;
LARGE_INTEGER diskLengthInfo;
DISK_GEOMETRY_EX dg;
STORAGE_PROPERTY_QUERY storagePropertyQuery = {0};
- byte* dgBuffer;
+ uint8* dgBuffer;
STORAGE_DEVICE_NUMBER storageDeviceNumber;
ntStatus = IoGetDeviceObjectPointer (&FullFileName,
FILE_READ_DATA | FILE_READ_ATTRIBUTES,
&Extension->pfoDeviceFile,
&Extension->pFsdDevice);
if (!NT_SUCCESS (ntStatus))
goto error;
dgBuffer = TCalloc (256);
if (!dgBuffer)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto error;
}
ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, (char *) dgBuffer, 256);
if (!NT_SUCCESS (ntStatus))
{
DISK_GEOMETRY geo;
ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &geo, sizeof (geo));
if (!NT_SUCCESS (ntStatus))
{
TCfree (dgBuffer);
goto error;
}
memset (&dg, 0, sizeof (dg));
memcpy (&dg.Geometry, &geo, sizeof (geo));
dg.DiskSize.QuadPart = geo.Cylinders.QuadPart * geo.SectorsPerTrack * geo.TracksPerCylinder * geo.BytesPerSector;
@@ -620,94 +622,96 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
mount->bCachePim,
readBuffer,
&mount->VolumePassword,
mount->pkcs5_prf,
mount->VolumePim,
&Extension->cryptoInfo);
}
ReadVolumeHeaderRecoveryMode = FALSE;
if (mount->nReturnCode == 0 || mount->nReturnCode == ERR_CIPHER_INIT_WEAK_KEY)
{
/* Volume header successfully decrypted */
if (!Extension->cryptoInfo)
{
/* should never happen */
mount->nReturnCode = ERR_OUTOFMEMORY;
ntStatus = STATUS_SUCCESS;
goto error;
}
#ifdef _WIN64
if (IsRamEncryptionEnabled() && (volumeType == TC_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume))
VcProtectKeys (Extension->cryptoInfo, VcGetEncryptionID (Extension->cryptoInfo));
#endif
Dump ("Volume header decrypted\n");
Dump ("Required program version = %x\n", (int) Extension->cryptoInfo->RequiredProgramVersion);
Dump ("Legacy volume = %d\n", (int) Extension->cryptoInfo->LegacyVolume);
+ Dump ("Master key vulnerable = %d\n", (int) Extension->cryptoInfo->bVulnerableMasterKey);
+
+ mount->VolumeMasterKeyVulnerable = Extension->cryptoInfo->bVulnerableMasterKey;
if (IsHiddenSystemRunning() && !Extension->cryptoInfo->hiddenVolume)
{
Extension->bReadOnly = mount->bMountReadOnly = TRUE;
HiddenSysLeakProtectionCount++;
}
Extension->cryptoInfo->bProtectHiddenVolume = FALSE;
Extension->cryptoInfo->bHiddenVolProtectionAction = FALSE;
Extension->cryptoInfo->bPartitionInInactiveSysEncScope = mount->bPartitionInInactiveSysEncScope;
/* compute the ID of this volume: SHA-256 of the effective header */
sha256 (Extension->volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
if (volumeType == TC_VOLUME_TYPE_NORMAL)
{
if (mount->bPartitionInInactiveSysEncScope)
{
if (Extension->cryptoInfo->EncryptedAreaStart.Value > (unsigned __int64) partitionStartingOffset
|| Extension->cryptoInfo->EncryptedAreaStart.Value + Extension->cryptoInfo->VolumeSize.Value <= (unsigned __int64) partitionStartingOffset)
{
// The partition is not within the key scope of system encryption
mount->nReturnCode = ERR_PASSWORD_WRONG;
ntStatus = STATUS_SUCCESS;
goto error;
}
if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
{
- // Partial encryption is not supported for volumes mounted as regular
- mount->nReturnCode = ERR_ENCRYPTION_NOT_COMPLETED;
- ntStatus = STATUS_SUCCESS;
- goto error;
+ // mount as readonly in case of partial system encryption
+ Extension->bReadOnly = mount->bMountReadOnly = TRUE;
+ mount->VolumeMountedReadOnlyAfterPartialSysEnc = TRUE;
}
}
else if (Extension->cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC)
{
if (Extension->cryptoInfo->EncryptedAreaLength.Value != Extension->cryptoInfo->VolumeSize.Value)
{
// Non-system in-place encryption process has not been completed on this volume
mount->nReturnCode = ERR_NONSYS_INPLACE_ENC_INCOMPLETE;
ntStatus = STATUS_SUCCESS;
goto error;
}
}
}
Extension->cryptoInfo->FirstDataUnitNo.Value = 0;
if (Extension->cryptoInfo->hiddenVolume && IsHiddenSystemRunning())
{
// Prevent mount of a hidden system partition if the system hosted on it is currently running
if (memcmp (Extension->cryptoInfo->master_keydata_hash, GetSystemDriveCryptoInfo()->master_keydata_hash, sizeof(Extension->cryptoInfo->master_keydata_hash)) == 0)
{
mount->nReturnCode = ERR_VOL_ALREADY_MOUNTED;
ntStatus = STATUS_SUCCESS;
goto error;
}
}
switch (volumeType)
{
case TC_VOLUME_TYPE_NORMAL:
@@ -771,62 +775,61 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject,
break;
}
Dump ("Volume data offset = %I64d\n", Extension->cryptoInfo->volDataAreaOffset);
Dump ("Volume data size = %I64d\n", Extension->DiskLength);
Dump ("Volume data end = %I64d\n", Extension->cryptoInfo->volDataAreaOffset + Extension->DiskLength - 1);
if (Extension->DiskLength == 0)
{
Dump ("Incorrect volume size\n");
continue;
}
// If this is a hidden volume, make sure we are supposed to actually
// mount it (i.e. not just to protect it)
if (volumeType == TC_VOLUME_TYPE_NORMAL || !mount->bProtectHiddenVolume)
{
// Validate sector size
if (bRawDevice && Extension->cryptoInfo->SectorSize != Extension->HostBytesPerSector)
{
mount->nReturnCode = ERR_PARAMETER_INCORRECT;
ntStatus = STATUS_SUCCESS;
goto error;
}
// Calculate virtual volume geometry
Extension->TracksPerCylinder = 1;
Extension->SectorsPerTrack = 1;
Extension->BytesPerSector = Extension->cryptoInfo->SectorSize;
- // Add extra sector since our virtual partition starts at Extension->BytesPerSector and not 0
- Extension->NumberOfCylinders = (Extension->DiskLength / Extension->BytesPerSector) + 1;
+ Extension->NumberOfCylinders = Extension->DiskLength / Extension->BytesPerSector;
Extension->PartitionType = 0;
Extension->bRawDevice = bRawDevice;
memset (Extension->wszVolume, 0, sizeof (Extension->wszVolume));
if ((wcslen (pwszMountVolume) > 8) && (0 == memcmp (pwszMountVolume, WIDE ("\\??\\UNC\\"), 8 * sizeof (WCHAR))))
{
/* UNC path */
RtlStringCbPrintfW (Extension->wszVolume,
sizeof (Extension->wszVolume),
WIDE ("\\??\\\\%s"),
pwszMountVolume + 7);
}
else
{
RtlStringCbCopyW (Extension->wszVolume, sizeof(Extension->wszVolume),pwszMountVolume);
}
memset (Extension->wszLabel, 0, sizeof (Extension->wszLabel));
RtlStringCbCopyW (Extension->wszLabel, sizeof(Extension->wszLabel), mount->wszLabel);
}
// If we are to protect a hidden volume we cannot exit yet, for we must also
// decrypt the hidden volume header.
if (!(volumeType == TC_VOLUME_TYPE_NORMAL && mount->bProtectHiddenVolume))
{
/* in case of mounting with hidden volume protection, we cache both passwords manually after bother outer and hidden volumes are mounted*/
if (mount->bProtectHiddenVolume && mount->bCache)
{
AddPasswordToCache(&mount->VolumePassword, mount->VolumePim, mount->bCachePim);