Author: tkreuzer Date: Sun Sep 14 19:40:15 2014 New Revision: 64153
URL: http://svn.reactos.org/svn/reactos?rev=64153&view=rev Log: [KSECDD] - Fix a typo in KsecQueryFileInformation - Implement missing ioctls in KsecDeviceControl - Support METHOD_OUT_DIRECT for IRP_MJ_DEVICE_CONTROL - Add stubs for KsecEn/DecryptMemory [ADVAPI32] - Use ksecdd to handle SystemFunction040 (RtlEncryptMemory) and SystemFunction041 (RtlDecryptMemory) (they still do nothing, but at least they do it in kenrnel mode now ;-))
Added: trunk/reactos/drivers/crypto/ksecdd/crypt.c (with props) Modified: trunk/reactos/dll/win32/advapi32/CMakeLists.txt trunk/reactos/dll/win32/advapi32/misc/dllmain.c trunk/reactos/dll/win32/advapi32/misc/sysfunc.c trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt trunk/reactos/drivers/crypto/ksecdd/dispatch.c trunk/reactos/drivers/crypto/ksecdd/ksecdd.h trunk/reactos/include/reactos/drivers/ksecdd/ksecioctl.h
Modified: trunk/reactos/dll/win32/advapi32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/CMakeLis... ============================================================================== --- trunk/reactos/dll/win32/advapi32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/CMakeLists.txt [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -8,6 +8,7 @@
include_directories( ${REACTOS_SOURCE_DIR}/include/reactos/idl + ${REACTOS_SOURCE_DIR}/include/reactos/drivers/ksecdd ${REACTOS_SOURCE_DIR}/lib/cryptlib ${CMAKE_CURRENT_BINARY_DIR})
Modified: trunk/reactos/dll/win32/advapi32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/misc/dll... ============================================================================== --- trunk/reactos/dll/win32/advapi32/misc/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/misc/dllmain.c [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -14,6 +14,7 @@ extern BOOL RegInitialize(VOID); extern BOOL RegCleanup(VOID); extern VOID UnloadNtMarta(VOID); +extern VOID CloseKsecDdHandle(VOID);
BOOL WINAPI @@ -33,6 +34,7 @@ CloseLogonLsaHandle(); RegCleanup(); UnloadNtMarta(); + CloseKsecDdHandle(); break; }
Modified: trunk/reactos/dll/win32/advapi32/misc/sysfunc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/misc/sys... ============================================================================== --- trunk/reactos/dll/win32/advapi32/misc/sysfunc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/misc/sysfunc.c [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -12,9 +12,15 @@ */
#include <advapi32.h> +#include <ksecioctl.h> #include <md4.h> #include <md5.h> #include <rc4.h> + +/* FIXME: this should be in some shared header */ +#define RTL_ENCRYPT_OPTION_SAME_PROCESS 0 +#define RTL_ENCRYPT_OPTION_CROSS_PROCESS 1 +#define RTL_ENCRYPT_OPTION_SAME_LOGON 2
static const unsigned char CRYPT_LMhash_Magic[8] = { 'K', 'G', 'S', '!', '@', '#', '$', '%' }; @@ -615,6 +621,93 @@ return TRUE; }
+HANDLE KsecDeviceHandle; + +static +NTSTATUS +KsecOpenDevice() +{ + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\Device\KsecDD"); + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE DeviceHandle; + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + 0x18, + NULL, + NULL); + Status = NtOpenFile(&DeviceHandle, + 0x100001, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (InterlockedCompareExchangePointer(&KsecDeviceHandle, DeviceHandle, NULL) != NULL) + { + NtClose(DeviceHandle); + } + + return STATUS_SUCCESS; +} + +VOID +CloseKsecDdHandle(VOID) +{ + /* Check if we already opened a handle to ksecdd */ + if (KsecDeviceHandle != NULL) + { + /* Close it */ + CloseHandle(KsecDeviceHandle); + KsecDeviceHandle = NULL; + } +} + +static +NTSTATUS +KsecDeviceIoControl( + ULONG IoControlCode, + PVOID InputBuffer, + SIZE_T InputBufferLength, + PVOID OutputBuffer, + SIZE_T OutputBufferLength) +{ + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + + /* Check if we already have a handle */ + if (KsecDeviceHandle == NULL) + { + /* Try to open the device */ + Status = KsecOpenDevice(); + if (!NT_SUCCESS(Status)) + { + //ERR("Failed to open handle to KsecDd driver!\n"); + return Status; + } + } + + /* Call the driver */ + Status = NtDeviceIoControlFile(KsecDeviceHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + IoControlCode, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength); + + return Status; +} + /* These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory, in crypt32.dll. @@ -642,10 +735,36 @@ * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */ -NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) -{ +NTSTATUS +WINAPI +SystemFunction040( + _Inout_ PVOID Memory, + _In_ ULONG MemoryLength, + _In_ ULONG OptionFlags) +{ + ULONG IoControlCode; + //FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory, length, flags); return STATUS_SUCCESS; + + if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS) + { + IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_PROCESS; + } + else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS) + { + IoControlCode = IOCTL_KSEC_ENCRYPT_CROSS_PROCESS; + } + else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON) + { + IoControlCode = IOCTL_KSEC_ENCRYPT_SAME_LOGON; + } + else + { + return STATUS_INVALID_PARAMETER; + } + + return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength); }
/****************************************************************************** @@ -670,10 +789,36 @@ * If flags are specified when encrypting, the same flag value must be given * when decrypting the memory. */ -NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) -{ +NTSTATUS +WINAPI +SystemFunction041( + _Inout_ PVOID Memory, + _In_ ULONG MemoryLength, + _In_ ULONG OptionFlags) +{ + ULONG IoControlCode; + //FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory, length, flags); return STATUS_SUCCESS; + + if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_PROCESS) + { + IoControlCode = IOCTL_KSEC_DECRYPT_SAME_PROCESS; + } + else if (OptionFlags == RTL_ENCRYPT_OPTION_CROSS_PROCESS) + { + IoControlCode = IOCTL_KSEC_DECRYPT_CROSS_PROCESS; + } + else if (OptionFlags == RTL_ENCRYPT_OPTION_SAME_LOGON) + { + IoControlCode = IOCTL_KSEC_DECRYPT_SAME_LOGON; + } + else + { + return STATUS_INVALID_PARAMETER; + } + + return KsecDeviceIoControl(IoControlCode, Memory, MemoryLength, Memory, MemoryLength); }
/* EOF */
Modified: trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/CMake... ============================================================================== --- trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -8,6 +8,7 @@ list(APPEND SOURCE ksecdd.c dispatch.c + crypt.c random.c stubs.c ksecdd.rc
Added: trunk/reactos/drivers/crypto/ksecdd/crypt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/crypt... ============================================================================== --- trunk/reactos/drivers/crypto/ksecdd/crypt.c (added) +++ trunk/reactos/drivers/crypto/ksecdd/crypt.c [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -0,0 +1,31 @@ +/* + * PROJECT: ReactOS Drivers + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: Kernel Security Support Provider Interface Driver + * + * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include "ksecdd.h" + +NTSTATUS +NTAPI +KsecEncryptMemory ( + _Inout_ PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG OptionFlags) +{ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +KsecDecryptMemory ( + _Inout_ PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG OptionFlags) +{ + return STATUS_SUCCESS; +}
Propchange: trunk/reactos/drivers/crypto/ksecdd/crypt.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/crypto/ksecdd/dispatch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/dispa... ============================================================================== --- trunk/reactos/drivers/crypto/ksecdd/dispatch.c [iso-8859-1] (original) +++ trunk/reactos/drivers/crypto/ksecdd/dispatch.c [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -33,7 +33,7 @@ }
/* Validate buffer size */ - if (*BufferLength >= sizeof(FILE_STANDARD_INFORMATION)) + if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION)) { *BufferLength = sizeof(FILE_STANDARD_INFORMATION); return STATUS_INFO_LENGTH_MISMATCH; @@ -92,7 +92,28 @@ { NTSTATUS Status;
- Status = STATUS_SUCCESS; + if ((IoControlCode == IOCTL_KSEC_RANDOM_FILL_BUFFER) || + (IoControlCode == IOCTL_KSEC_ENCRYPT_SAME_PROCESS) || + (IoControlCode == IOCTL_KSEC_DECRYPT_SAME_PROCESS) || + (IoControlCode == IOCTL_KSEC_ENCRYPT_CROSS_PROCESS) || + (IoControlCode == IOCTL_KSEC_DECRYPT_CROSS_PROCESS) || + (IoControlCode == IOCTL_KSEC_ENCRYPT_SAME_LOGON) || + (IoControlCode == IOCTL_KSEC_DECRYPT_SAME_LOGON)) + { + /* Make sure we have a valid output buffer */ + if ((Buffer == NULL) || (OutputLength == NULL)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Check if the input is smaller than the output */ + if (InputLength < *OutputLength) + { + /* We might have uninitialized memory, zero it out */ + RtlSecureZeroMemory((PUCHAR)Buffer + InputLength, + *OutputLength - InputLength); + } + }
/* Check ioctl code */ switch (IoControlCode) @@ -105,6 +126,48 @@ case IOCTL_KSEC_RANDOM_FILL_BUFFER:
Status = KsecGenRandom(Buffer, *OutputLength); + break; + + case IOCTL_KSEC_ENCRYPT_SAME_PROCESS: + + Status = KsecEncryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_SAME_PROCESS); + break; + + case IOCTL_KSEC_DECRYPT_SAME_PROCESS: + + Status = KsecDecryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_SAME_PROCESS); + break; + + case IOCTL_KSEC_ENCRYPT_CROSS_PROCESS: + + Status = KsecEncryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_CROSS_PROCESS); + break; + + case IOCTL_KSEC_DECRYPT_CROSS_PROCESS: + + Status = KsecDecryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_CROSS_PROCESS); + break; + + case IOCTL_KSEC_ENCRYPT_SAME_LOGON: + + Status = KsecEncryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_SAME_LOGON); + break; + + case IOCTL_KSEC_DECRYPT_SAME_LOGON: + + Status = KsecDecryptMemory(Buffer, + *OutputLength, + RTL_ENCRYPT_OPTION_SAME_LOGON); break;
default: @@ -188,10 +251,30 @@ case IRP_MJ_DEVICE_CONTROL:
/* Extract the parameters */ - Buffer = Irp->AssociatedIrp.SystemBuffer; InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; + + /* Check for METHOD_OUT_DIRECT method */ + if ((METHOD_FROM_CTL_CODE(IoControlCode) == METHOD_OUT_DIRECT) && + (OutputLength != 0)) + { + /* Use the provided MDL */ + OutputLength = Irp->MdlAddress->ByteCount; + Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, + NormalPagePriority); + if (Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + Information = 0; + break; + } + } + else + { + /* Otherwise this is METHOD_BUFFERED, use the SystemBuffer */ + Buffer = Irp->AssociatedIrp.SystemBuffer; + }
/* Call the internal function */ Status = KsecDeviceControl(IoControlCode, @@ -205,6 +288,7 @@ DPRINT1("Unhandled major function %lu!\n", IoStackLocation->MajorFunction); ASSERT(FALSE); + return STATUS_INVALID_DEVICE_REQUEST; }
/* Return the information */
Modified: trunk/reactos/drivers/crypto/ksecdd/ksecdd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/ksecd... ============================================================================== --- trunk/reactos/drivers/crypto/ksecdd/ksecdd.h [iso-8859-1] (original) +++ trunk/reactos/drivers/crypto/ksecdd/ksecdd.h [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -9,6 +9,26 @@ #define _NO_KSECDD_IMPORT_ #include <ntifs.h> #include <ndk/extypes.h> +#include <ndk/rtlfuncs.h> +#include <ndk/lpcfuncs.h> +#include <ndk/obfuncs.h> +#include <ntstrsafe.h> + +#define STATUS_KSEC_INTERNAL_ERROR ((NTSTATUS)0x80090304) + +/* FIXME: this should be in some shared header */ +#define RTL_ENCRYPT_OPTION_SAME_PROCESS 0 +#define RTL_ENCRYPT_OPTION_CROSS_PROCESS 1 +#define RTL_ENCRYPT_OPTION_SAME_LOGON 2 + +typedef struct _KSEC_CONNECTION_INFO +{ + ULONG Unknown0; + NTSTATUS Status; + ULONG_PTR Information; + CHAR ConnectionString[128]; + ULONG Flags; +} KSEC_CONNECTION_INFO;
#if defined(_M_IX86) || defined(_M_AMD64) typedef struct _KSEC_MACHINE_SPECIFIC_COUNTERS @@ -41,6 +61,9 @@ SYSTEM_PROCESS_INFORMATION SystemProcessInformation; } KSEC_ENTROPY_DATA, *PKSEC_ENTROPY_DATA;
+extern PEPROCESS KsecLsaProcess;; +extern HANDLE KsecLsaProcessHandle; + NTSTATUS NTAPI KsecDdDispatch( @@ -54,3 +77,37 @@ PVOID Buffer, SIZE_T Length);
+NTSTATUS +NTAPI +KsecEncryptMemory ( + _Inout_ PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG OptionFlags); + +NTSTATUS +NTAPI +KsecDecryptMemory ( + _Inout_ PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG OptionFlags); + +NTSTATUS +NTAPI +KsecInitLsaMemory(VOID); + +/// +PVOID +NTAPI +PsGetProcessSecurityPort( + PEPROCESS Process); + +NTSTATUS +NTAPI +PsSetProcessSecurityPort( + PEPROCESS Process, + PVOID SecurityPort); + +HANDLE +NTAPI +PsGetCurrentThreadProcessId(VOID); +
Modified: trunk/reactos/include/reactos/drivers/ksecdd/ksecioctl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/drivers/kse... ============================================================================== --- trunk/reactos/include/reactos/drivers/ksecdd/ksecioctl.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/drivers/ksecdd/ksecioctl.h [iso-8859-1] Sun Sep 14 19:40:15 2014 @@ -15,11 +15,11 @@ CTL_CODE(FILE_DEVICE_KSEC, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 3: 0x39000E - called from SystemFunction040 aka RtlEncryptMemory with OptionFlags == 0 -#define IOCTL_KSEC_ENCRYPT_PROCESS \ +#define IOCTL_KSEC_ENCRYPT_SAME_PROCESS \ CTL_CODE(FILE_DEVICE_KSEC, 0x03, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
// 4: 0x390012 - called from SystemFunction041 aka RtlDecryptMemory with OptionFlags == 0 -#define IOCTL_KSEC_DECRYPT_PROCESS \ +#define IOCTL_KSEC_DECRYPT_SAME_PROCESS \ CTL_CODE(FILE_DEVICE_KSEC, 0x04, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
// 5: 0x390016 - called from SystemFunction040 aka RtlEncryptMemory with OptionFlags == 1