diff options
-rw-r--r-- | src/Common/Apidrvr.h | 2 | ||||
-rw-r--r-- | src/Common/Crypto.c | 10 | ||||
-rw-r--r-- | src/Common/Crypto.h | 1 | ||||
-rw-r--r-- | src/Driver/DriveFilter.c | 61 | ||||
-rw-r--r-- | src/Driver/DriveFilter.h | 3 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.c | 4 | ||||
-rw-r--r-- | src/Driver/EncryptedIoQueue.h | 4 | ||||
-rw-r--r-- | src/Driver/Ntdriver.c | 5 | ||||
-rw-r--r-- | src/Driver/Ntdriver.h | 3 |
9 files changed, 87 insertions, 6 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 2043a211..2d996d2c 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -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 diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 00d44a93..f63062a3 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -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) diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index e66cfbab..07f6c069 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -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); diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 2daf1f52..1ed6f8a3 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -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) { diff --git a/src/Driver/DriveFilter.h b/src/Driver/DriveFilter.h index 9ce151c7..17459cbc 100644 --- a/src/Driver/DriveFilter.h +++ b/src/Driver/DriveFilter.h @@ -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 (); diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c index f7e453fd..6f1d3777 100644 --- a/src/Driver/EncryptedIoQueue.c +++ b/src/Driver/EncryptedIoQueue.c @@ -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) { diff --git a/src/Driver/EncryptedIoQueue.h b/src/Driver/EncryptedIoQueue.h index c4a105e8..58efbc96 100644 --- a/src/Driver/EncryptedIoQueue.h +++ b/src/Driver/EncryptedIoQueue.h @@ -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; diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 780db9dc..47b2f8a5 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -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; diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h index 2479d45b..4ee25454 100644 --- a/src/Driver/Ntdriver.h +++ b/src/Driver/Ntdriver.h @@ -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') |