- 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:
Timo Kreuzer 2014-09-14 19:40:15 +00:00
parent 00ad9c4760
commit fe8e1d19fb
8 changed files with 328 additions and 7 deletions

View file

@ -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})

View file

@ -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;
}

View file

@ -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 */

View file

@ -8,6 +8,7 @@ include_directories(
list(APPEND SOURCE
ksecdd.c
dispatch.c
crypt.c
random.c
stubs.c
ksecdd.rc

View 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;
}

View file

@ -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 */

View file

@ -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);

View file

@ -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