mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-28 05:53:29 +01:00
Windows Security: Add new entry point in driver that allows emergency clearing of all encryption keys from memory. This entry point requires administrative privileges and it will caused BSDO when system encryption is active. It can be useful for example to applications that monitors physical access to the machine and which need to erase sensitive key material from RAM when unauthorized access is detected.
This commit is contained in:
parent
7c2cf7889f
commit
652e989d23
@ -123,6 +123,8 @@
|
||||
// IN OUT - DISK_GEOMETRY_EX_STRUCT
|
||||
#define VC_IOCTL_GET_DRIVE_GEOMETRY_EX TC_IOCTL (40)
|
||||
|
||||
#define VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS TC_IOCTL (41)
|
||||
|
||||
// Legacy IOCTLs used before version 5.0
|
||||
#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
|
||||
#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
|
||||
|
@ -884,6 +884,16 @@ void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
|
||||
burn (keyInfo->userKey, sizeof (keyInfo->userKey));
|
||||
memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
|
||||
}
|
||||
|
||||
void crypto_eraseKeys (PCRYPTO_INFO cryptoInfo)
|
||||
{
|
||||
burn (cryptoInfo->ks, sizeof (cryptoInfo->ks));
|
||||
burn (cryptoInfo->ks2, sizeof (cryptoInfo->ks2));
|
||||
burn (cryptoInfo->master_keydata, sizeof (cryptoInfo->master_keydata));
|
||||
burn (cryptoInfo->k2, sizeof (cryptoInfo->k2));
|
||||
burn (&cryptoInfo->noIterations, sizeof (cryptoInfo->noIterations));
|
||||
burn (&cryptoInfo->volumePim, sizeof (cryptoInfo->volumePim));
|
||||
}
|
||||
#endif
|
||||
|
||||
void crypto_close (PCRYPTO_INFO cryptoInfo)
|
||||
|
@ -306,6 +306,7 @@ typedef struct BOOT_CRYPTO_HEADER_t
|
||||
PCRYPTO_INFO crypto_open (void);
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen);
|
||||
void crypto_eraseKeys (PCRYPTO_INFO cryptoInfo);
|
||||
#endif
|
||||
void crypto_close (PCRYPTO_INFO cryptoInfo);
|
||||
|
||||
|
@ -288,13 +288,40 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue)
|
||||
if (stopIoQueue && EncryptedIoQueueIsRunning (&Extension->Queue))
|
||||
EncryptedIoQueueStop (&Extension->Queue);
|
||||
|
||||
crypto_close (Extension->Queue.CryptoInfo);
|
||||
crypto_close ((PCRYPTO_INFO) Extension->Queue.CryptoInfo);
|
||||
Extension->Queue.CryptoInfo = NULL;
|
||||
|
||||
crypto_close (Extension->HeaderCryptoInfo);
|
||||
crypto_close ((PCRYPTO_INFO) Extension->HeaderCryptoInfo);
|
||||
Extension->HeaderCryptoInfo = NULL;
|
||||
|
||||
Extension->DriveMounted = FALSE;
|
||||
|
||||
Dump ("Drive dismount done!\n");
|
||||
}
|
||||
|
||||
static void InvalidateVolumeKeys (EXTENSION *Extension)
|
||||
{
|
||||
Dump ("Invalidating volume encryption keys\n");
|
||||
|
||||
Extension->Queue.ThreadBlockReadWrite = TRUE;
|
||||
|
||||
crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo);
|
||||
crypto_eraseKeys ((PCRYPTO_INFO) Extension->cryptoInfo);
|
||||
|
||||
Dump ("Volume encryption keys invalidated!\n");
|
||||
}
|
||||
|
||||
static void InvalidateDriveFilterKeys (DriveFilterExtension *Extension)
|
||||
{
|
||||
Dump ("Invalidating drive filter encryption keys\n");
|
||||
ASSERT (Extension->DriveMounted);
|
||||
|
||||
Extension->Queue.ThreadBlockReadWrite = TRUE;
|
||||
|
||||
crypto_eraseKeys ((PCRYPTO_INFO) Extension->Queue.CryptoInfo);
|
||||
crypto_eraseKeys ((PCRYPTO_INFO) Extension->HeaderCryptoInfo);
|
||||
|
||||
Dump ("Drive filter encryption keys invalidated!\n");
|
||||
}
|
||||
|
||||
static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* ioBuffer /* ioBuffer must be at least 512 bytes long */)
|
||||
@ -1025,6 +1052,36 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
return status;
|
||||
}
|
||||
|
||||
void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
{
|
||||
irp->IoStatus.Information = 0;
|
||||
|
||||
if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice())
|
||||
{
|
||||
irp->IoStatus.Status = STATUS_ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
int drive;
|
||||
for (drive = MIN_MOUNTED_VOLUME_DRIVE_NUMBER; drive <= MAX_MOUNTED_VOLUME_DRIVE_NUMBER; ++drive)
|
||||
{
|
||||
PDEVICE_OBJECT device = GetVirtualVolumeDeviceObject (drive);
|
||||
if (device)
|
||||
{
|
||||
PEXTENSION extension = (PEXTENSION) device->DeviceExtension;
|
||||
if (extension)
|
||||
{
|
||||
InvalidateVolumeKeys (extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted)
|
||||
InvalidateDriveFilterKeys (BootDriveFilterExtension);
|
||||
|
||||
irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ typedef struct _DriveFilterExtension
|
||||
|
||||
KEVENT MountWorkItemCompletedEvent;
|
||||
|
||||
CRYPTO_INFO *HeaderCryptoInfo;
|
||||
volatile CRYPTO_INFO *HeaderCryptoInfo;
|
||||
BOOL HiddenSystem;
|
||||
|
||||
} DriveFilterExtension;
|
||||
@ -73,6 +73,7 @@ BOOL IsHiddenSystemRunning ();
|
||||
NTSTATUS LoadBootArguments ();
|
||||
static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension);
|
||||
NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp);
|
||||
void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp);
|
||||
void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp);
|
||||
NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp);
|
||||
void StartLegacyHibernationDriverFilter ();
|
||||
|
@ -383,7 +383,9 @@ static VOID IoThreadProc (PVOID threadArg)
|
||||
// Perform IO request if no preceding request of the item failed
|
||||
if (NT_SUCCESS (request->Item->Status))
|
||||
{
|
||||
if (queue->IsFilterDevice)
|
||||
if (queue->ThreadBlockReadWrite)
|
||||
request->Item->Status = STATUS_DEVICE_BUSY;
|
||||
else if (queue->IsFilterDevice)
|
||||
{
|
||||
if (queue->RemapEncryptedArea && request->EncryptedLength > 0)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ typedef struct
|
||||
KMUTEX BufferPoolMutex;
|
||||
EncryptedIoQueueBuffer *FirstPoolBuffer;
|
||||
|
||||
CRYPTO_INFO *CryptoInfo;
|
||||
volatile CRYPTO_INFO *CryptoInfo;
|
||||
|
||||
// File-handle-based IO
|
||||
HANDLE HostFileHandle;
|
||||
@ -119,6 +119,8 @@ typedef struct
|
||||
|
||||
byte* SecRegionData;
|
||||
SIZE_T SecRegionSize;
|
||||
|
||||
volatile BOOL ThreadBlockReadWrite;
|
||||
} EncryptedIoQueue;
|
||||
|
||||
|
||||
|
@ -2507,6 +2507,11 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
|
||||
}
|
||||
break;
|
||||
|
||||
case VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS:
|
||||
EmergencyClearAllKeys (Irp, irpSp);
|
||||
WipeCache();
|
||||
break;
|
||||
|
||||
case TC_IOCTL_BOOT_ENCRYPTION_SETUP:
|
||||
Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp);
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -51,7 +51,7 @@ typedef struct EXTENSION
|
||||
PFILE_OBJECT pfoDeviceFile; /* Device fileobject for this device */
|
||||
PDEVICE_OBJECT pFsdDevice; /* lower level device handle */
|
||||
|
||||
CRYPTO_INFO *cryptoInfo; /* Cryptographic and other information for this device */
|
||||
volatile CRYPTO_INFO *cryptoInfo; /* Cryptographic and other information for this device */
|
||||
|
||||
__int64 HostLength;
|
||||
__int64 DiskLength; /* The length of the disk referred to by this device */
|
||||
@ -190,6 +190,7 @@ BOOL IsVolumeAccessibleByCurrentUser (PEXTENSION volumeDeviceExtension);
|
||||
void GetElapsedTimeInit (LARGE_INTEGER *lastPerfCounter);
|
||||
int64 GetElapsedTime (LARGE_INTEGER *lastPerfCounter);
|
||||
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
|
||||
PDEVICE_OBJECT GetVirtualVolumeDeviceObject (int driveNumber);
|
||||
|
||||
#define TC_BUG_CHECK(status) KeBugCheckEx (SECURITY_SYSTEM, __LINE__, (ULONG_PTR) status, 0, 'VC')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user