mirror of
https://github.com/reactos/reactos.git
synced 2025-05-22 10:35:54 +00:00
[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 ;-)) svn path=/trunk/; revision=64153
This commit is contained in:
parent
00ad9c4760
commit
fe8e1d19fb
8 changed files with 328 additions and 7 deletions
|
@ -8,6 +8,7 @@ add_definitions(-D_WIN32_WINNT=0x600)
|
|||
|
||||
include_directories(
|
||||
${REACTOS_SOURCE_DIR}/include/reactos/idl
|
||||
${REACTOS_SOURCE_DIR}/include/reactos/drivers/ksecdd
|
||||
${REACTOS_SOURCE_DIR}/lib/cryptlib
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi);
|
|||
extern BOOL RegInitialize(VOID);
|
||||
extern BOOL RegCleanup(VOID);
|
||||
extern VOID UnloadNtMarta(VOID);
|
||||
extern VOID CloseKsecDdHandle(VOID);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
|
@ -33,6 +34,7 @@ DllMain(
|
|||
CloseLogonLsaHandle();
|
||||
RegCleanup();
|
||||
UnloadNtMarta();
|
||||
CloseKsecDdHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,16 @@
|
|||
*/
|
||||
|
||||
#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 @@ SystemFunction036(PVOID pbBuffer, ULONG dwLen)
|
|||
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 @@ SystemFunction036(PVOID pbBuffer, ULONG dwLen)
|
|||
* 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 @@ NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags)
|
|||
* 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 */
|
||||
|
|
|
@ -8,6 +8,7 @@ include_directories(
|
|||
list(APPEND SOURCE
|
||||
ksecdd.c
|
||||
dispatch.c
|
||||
crypt.c
|
||||
random.c
|
||||
stubs.c
|
||||
ksecdd.rc
|
||||
|
|
31
reactos/drivers/crypto/ksecdd/crypt.c
Normal file
31
reactos/drivers/crypto/ksecdd/crypt.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -33,7 +33,7 @@ KsecQueryFileInformation(
|
|||
}
|
||||
|
||||
/* 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 @@ KsecDeviceControl(
|
|||
{
|
||||
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)
|
||||
|
@ -107,6 +128,48 @@ KsecDeviceControl(
|
|||
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:
|
||||
DPRINT1("Unhandled control code 0x%lx\n", IoControlCode);
|
||||
__debugbreak();
|
||||
|
@ -188,11 +251,31 @@ KsecDdDispatch(
|
|||
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,
|
||||
Buffer,
|
||||
|
@ -205,6 +288,7 @@ KsecDdDispatch(
|
|||
DPRINT1("Unhandled major function %lu!\n",
|
||||
IoStackLocation->MajorFunction);
|
||||
ASSERT(FALSE);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
/* Return the information */
|
||||
|
|
|
@ -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 @@ typedef struct _KSEC_ENTROPY_DATA
|
|||
SYSTEM_PROCESS_INFORMATION SystemProcessInformation;
|
||||
} KSEC_ENTROPY_DATA, *PKSEC_ENTROPY_DATA;
|
||||
|
||||
extern PEPROCESS KsecLsaProcess;;
|
||||
extern HANDLE KsecLsaProcessHandle;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KsecDdDispatch(
|
||||
|
@ -54,3 +77,37 @@ KsecGenRandom(
|
|||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue