Implement IRP_MJ_DEVICE_CONTROL, handle ioctl 0x390004, used by MS advapi32 to generate random numbers. Even though it is not very crypto-safe, for now we just use RtlRandomEx, "improved" by xoring the seed with some data from KeTickCount (no idea whether that does any good)

svn path=/trunk/; revision=61759
This commit is contained in:
Timo Kreuzer 2014-01-22 23:41:04 +00:00
parent 49ca94a0f8
commit 0739ebd3f9
5 changed files with 109 additions and 1 deletions

View file

@ -4,6 +4,7 @@ spec2def(ksecdd.sys ksecdd.spec)
list(APPEND SOURCE
ksecdd.c
dispatch.c
random.c
stubs.c
ksecdd.rc)

View file

@ -81,6 +81,35 @@ KsecQueryVolumeInformation(
return STATUS_SUCCESS;
}
static
NTSTATUS
KsecDeviceControl(
ULONG IoControlCode,
PVOID Buffer,
SIZE_T InputLength,
PSIZE_T OutputLength)
{
NTSTATUS Status;
Status = STATUS_SUCCESS;
/* Check ioctl code */
switch (IoControlCode)
{
case IOCTL_KSEC_GEN_RANDOM:
Status = KsecGenRandom(Buffer, *OutputLength);
break;
default:
DPRINT1("Unhandled control code 0x%lx\n", IoControlCode);
__debugbreak();
return STATUS_INVALID_PARAMETER;
}
return Status;
}
NTSTATUS
NTAPI
KsecDdDispatch(
@ -91,9 +120,10 @@ KsecDdDispatch(
ULONG_PTR Information;
NTSTATUS Status;
PVOID Buffer;
SIZE_T OutputLength;
SIZE_T InputLength, OutputLength;
FILE_INFORMATION_CLASS FileInfoClass;
FS_INFORMATION_CLASS FsInfoClass;
ULONG IoControlCode;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
@ -149,6 +179,22 @@ KsecDdDispatch(
Information = OutputLength;
break;
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;
/* Call the internal function */
Status = KsecDeviceControl(IoControlCode,
Buffer,
InputLength,
&OutputLength);
Information = OutputLength;
break;
default:
DPRINT1("Unhandled major function %lu!\n",
IoStackLocation->MajorFunction);

View file

@ -50,6 +50,7 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_WRITE] = KsecDdDispatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = KsecDdDispatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = KsecDdDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KsecDdDispatch;
return STATUS_SUCCESS;
}

View file

@ -9,6 +9,10 @@
#define _NO_KSECDD_IMPORT_
#include <ntifs.h>
// 0x390004
#define IOCTL_KSEC_GEN_RANDOM \
CTL_CODE(FILE_DEVICE_KSEC, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
NTSTATUS
NTAPI
KsecDdDispatch(
@ -16,3 +20,9 @@ KsecDdDispatch(
PIRP Irp);
NTSTATUS
NTAPI
KsecGenRandom(
PVOID Buffer,
SIZE_T Length);

View file

@ -0,0 +1,50 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Drivers
* PURPOSE: Kernel Security Support Provider Interface Driver
*
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include "ksecdd.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
static ULONG KsecRandomSeed = 0x62b409a1;
/* FUNCTIONS ******************************************************************/
NTSTATUS
NTAPI
KsecGenRandom(
PVOID Buffer,
SIZE_T Length)
{
ULONG i, RandomValue;
PULONG P;
/* Try to generate a more random seed */
KsecRandomSeed ^= _rotl(KeTickCount.LowPart, (KsecRandomSeed % 23));
P = Buffer;
for (i = 0; i < Length / sizeof(ULONG); i++)
{
P[i] = RtlRandomEx(&KsecRandomSeed);
}
Length &= (sizeof(ULONG) - 1);
if (Length > 0)
{
RandomValue = RtlRandomEx(&KsecRandomSeed);
RtlCopyMemory(&P[i], &RandomValue, Length);
}
return STATUS_SUCCESS;
}