[KSECDD]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 22 Jan 2014 23:41:04 +0000 (23:41 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 22 Jan 2014 23:41:04 +0000 (23:41 +0000)
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
reactos/drivers/crypto/ksecdd/dispatch.c
reactos/drivers/crypto/ksecdd/ksecdd.c
reactos/drivers/crypto/ksecdd/ksecdd.h
reactos/drivers/crypto/ksecdd/random.c [new file with mode: 0644]

index 29163b4..070f927 100644 (file)
@@ -4,6 +4,7 @@ spec2def(ksecdd.sys ksecdd.spec)
 list(APPEND SOURCE
      ksecdd.c
      dispatch.c
+     random.c
      stubs.c
      ksecdd.rc)
 
index c1726df..fe6be34 100644 (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);
index c6513e2..d955b0f 100644 (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;
 }
index 098c77c..934152d 100644 (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);
+
diff --git a/reactos/drivers/crypto/ksecdd/random.c b/reactos/drivers/crypto/ksecdd/random.c
new file mode 100644 (file)
index 0000000..fdf724d
--- /dev/null
@@ -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;
+}