From 0739ebd3f93445f36be07fb0310e350b46e15fcd Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 22 Jan 2014 23:41:04 +0000 Subject: [PATCH] [KSECDD] 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 --- reactos/drivers/crypto/ksecdd/CMakeLists.txt | 1 + reactos/drivers/crypto/ksecdd/dispatch.c | 48 ++++++++++++++++++- reactos/drivers/crypto/ksecdd/ksecdd.c | 1 + reactos/drivers/crypto/ksecdd/ksecdd.h | 10 ++++ reactos/drivers/crypto/ksecdd/random.c | 50 ++++++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 reactos/drivers/crypto/ksecdd/random.c diff --git a/reactos/drivers/crypto/ksecdd/CMakeLists.txt b/reactos/drivers/crypto/ksecdd/CMakeLists.txt index 29163b45824..070f9278223 100644 --- a/reactos/drivers/crypto/ksecdd/CMakeLists.txt +++ b/reactos/drivers/crypto/ksecdd/CMakeLists.txt @@ -4,6 +4,7 @@ spec2def(ksecdd.sys ksecdd.spec) list(APPEND SOURCE ksecdd.c dispatch.c + random.c stubs.c ksecdd.rc) diff --git a/reactos/drivers/crypto/ksecdd/dispatch.c b/reactos/drivers/crypto/ksecdd/dispatch.c index c1726df161e..fe6be34331e 100644 --- a/reactos/drivers/crypto/ksecdd/dispatch.c +++ b/reactos/drivers/crypto/ksecdd/dispatch.c @@ -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); diff --git a/reactos/drivers/crypto/ksecdd/ksecdd.c b/reactos/drivers/crypto/ksecdd/ksecdd.c index c6513e247cc..d955b0f9365 100644 --- a/reactos/drivers/crypto/ksecdd/ksecdd.c +++ b/reactos/drivers/crypto/ksecdd/ksecdd.c @@ -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; } diff --git a/reactos/drivers/crypto/ksecdd/ksecdd.h b/reactos/drivers/crypto/ksecdd/ksecdd.h index 098c77c5df4..934152d9b91 100644 --- a/reactos/drivers/crypto/ksecdd/ksecdd.h +++ b/reactos/drivers/crypto/ksecdd/ksecdd.h @@ -9,6 +9,10 @@ #define _NO_KSECDD_IMPORT_ #include +// 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); + diff --git a/reactos/drivers/crypto/ksecdd/random.c b/reactos/drivers/crypto/ksecdd/random.c new file mode 100644 index 00000000000..fdf724d48db --- /dev/null +++ b/reactos/drivers/crypto/ksecdd/random.c @@ -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 + + +/* 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; +}