Author: tkreuzer
Date: Sun Jan 26 20:30:06 2014
New Revision: 61842
URL:
http://svn.reactos.org/svn/reactos?rev=61842&view=rev
Log:
[KSECDD]
- Fix a typo in KsecQueryVolumeInformation, noticed by Michael Fritscher
- Implement KsecGatherEntropyData, which will be used in generation of cryptographically
secure random numbers according to FIPS 186-2. Based on information from
http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
Modified:
trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt
trunk/reactos/drivers/crypto/ksecdd/dispatch.c
trunk/reactos/drivers/crypto/ksecdd/ksecdd.h
trunk/reactos/drivers/crypto/ksecdd/random.c
Modified: trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/CMak…
==============================================================================
--- trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/crypto/ksecdd/CMakeLists.txt [iso-8859-1] Sun Jan 26 20:30:06
2014
@@ -1,5 +1,9 @@
spec2def(ksecdd.sys ksecdd.spec)
+
+
+include_directories(
+ ${REACTOS_SOURCE_DIR}/lib/cryptlib)
list(APPEND SOURCE
ksecdd.c
@@ -9,6 +13,7 @@
ksecdd.rc)
add_library(ksecdd SHARED ${SOURCE})
+target_link_libraries(ksecdd cryptlib pseh)
set_module_type(ksecdd kernelmodedriver)
add_importlibs(ksecdd ntoskrnl hal)
add_cd_file(TARGET ksecdd DESTINATION reactos/system32/drivers NO_CAB FOR all)
Modified: trunk/reactos/drivers/crypto/ksecdd/dispatch.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/disp…
==============================================================================
--- trunk/reactos/drivers/crypto/ksecdd/dispatch.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/crypto/ksecdd/dispatch.c [iso-8859-1] Sun Jan 26 20:30:06 2014
@@ -60,7 +60,7 @@
PFILE_FS_DEVICE_INFORMATION DeviceInformation;
/* Only FileFsDeviceInformation is supported */
- if (FsInformationClass == FileFsDeviceInformation)
+ if (FsInformationClass != FileFsDeviceInformation)
{
return STATUS_INVALID_INFO_CLASS;
}
Modified: trunk/reactos/drivers/crypto/ksecdd/ksecdd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/ksec…
==============================================================================
--- trunk/reactos/drivers/crypto/ksecdd/ksecdd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/crypto/ksecdd/ksecdd.h [iso-8859-1] Sun Jan 26 20:30:06 2014
@@ -8,10 +8,42 @@
#define _NO_KSECDD_IMPORT_
#include <ntifs.h>
+#include <ndk/extypes.h>
// 0x390004
#define IOCTL_KSEC_GEN_RANDOM \
CTL_CODE(FILE_DEVICE_KSEC, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#if defined(_M_IX86) || defined(_M_AMD64)
+typedef struct _KSEC_MACHINE_SPECIFIC_COUNTERS
+{
+ ULONG64 Tsc;
+ ULONG64 Pmc0;
+ ULONG64 Pmc1;
+ ULONG64 Ctr0;
+ ULONG64 Ctr1;
+} KSEC_MACHINE_SPECIFIC_COUNTERS, *PKSEC_MACHINE_SPECIFIC_COUNTERS;
+#else
+typedef ULONG KSEC_MACHINE_SPECIFIC_COUNTERS;
+#endif
+
+typedef struct _KSEC_ENTROPY_DATA
+{
+ HANDLE CurrentProcessId;
+ HANDLE CurrentThreadId;
+ LARGE_INTEGER TickCount;
+ LARGE_INTEGER SystemTime;
+ LARGE_INTEGER PerformanceCounter;
+ LARGE_INTEGER PerformanceFrequency;
+ UCHAR EnvironmentHash[16];
+ KSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters;
+ SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorPerformanceInformation;
+ SYSTEM_PERFORMANCE_INFORMATION SystemPerformanceInformation;
+ SYSTEM_EXCEPTION_INFORMATION SystemExceptionInformation;
+ SYSTEM_LOOKASIDE_INFORMATION SystemLookasideInformation;
+ SYSTEM_INTERRUPT_INFORMATION SystemInterruptInformation;
+ SYSTEM_PROCESS_INFORMATION SystemProcessInformation;
+} KSEC_ENTROPY_DATA, *PKSEC_ENTROPY_DATA;
NTSTATUS
NTAPI
Modified: trunk/reactos/drivers/crypto/ksecdd/random.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/crypto/ksecdd/rand…
==============================================================================
--- trunk/reactos/drivers/crypto/ksecdd/random.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/crypto/ksecdd/random.c [iso-8859-1] Sun Jan 26 20:30:06 2014
@@ -9,6 +9,10 @@
/* INCLUDES *******************************************************************/
#include "ksecdd.h"
+#include <ndk/exfuncs.h>
+#include <ndk/kefuncs.h>
+#include <pseh/pseh2.h>
+#include <md4.h>
#define NDEBUG
#include <debug.h>
@@ -48,3 +52,154 @@
return STATUS_SUCCESS;
}
+
+VOID
+NTAPI
+KsecReadMachineSpecificCounters(
+ _Out_ PKSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters)
+{
+#if defined(_M_IX86) || defined(_M_AMD64)
+ /* Check if RDTSC is available */
+ if (ExIsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE))
+ {
+ /* Read the TSC value */
+ MachineSpecificCounters->Tsc = __rdtsc();
+ }
+
+ /* Read the CPU event counter MSRs */
+ MachineSpecificCounters->Ctr0 = __readmsr(0x12);
+ MachineSpecificCounters->Ctr1 = __readmsr(0x13);
+
+ /* Check if this is an MMX capable CPU */
+ if (ExIsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))
+ {
+ /* Read the CPU performance counters 0 and 1 */
+ MachineSpecificCounters->Pmc0 = __readpmc(0);
+ MachineSpecificCounters->Pmc1 = __readpmc(1);
+ }
+#else
+ #error Implement me!
+#endif
+}
+
+/*!
+ * \see
http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
+ */
+NTSTATUS
+NTAPI
+KsecGatherEntropyData(
+ PKSEC_ENTROPY_DATA EntropyData)
+{
+ MD4_CTX Md4Context;
+ PTEB Teb;
+ PPEB Peb;
+ PWSTR String;
+ ULONG ReturnLength;
+ NTSTATUS Status;
+
+ /* Query some generic values */
+ EntropyData->CurrentProcessId = PsGetCurrentProcessId();
+ EntropyData->CurrentThreadId = PsGetCurrentThreadId();
+ KeQueryTickCount(&EntropyData->TickCount);
+ KeQuerySystemTime(&EntropyData->SystemTime);
+ EntropyData->PerformanceCounter = KeQueryPerformanceCounter(
+ &EntropyData->PerformanceFrequency);
+
+ /* Check if we have a TEB/PEB for the process environment */
+ Teb = PsGetCurrentThread()->Tcb.Teb;
+ if (Teb != NULL)
+ {
+ Peb = Teb->ProcessEnvironmentBlock;
+
+ /* Initialize the MD4 context */
+ MD4Init(&Md4Context);
+ _SEH2_TRY
+ {
+ /* Get the end of the environment */
+ String = Peb->ProcessParameters->Environment;
+ while (*String)
+ {
+ String += wcslen(String) + 1;
+ }
+
+ /* Update the MD4 context from the environment data */
+ MD4Update(&Md4Context,
+ (PUCHAR)Peb->ProcessParameters->Environment,
+ (PUCHAR)String -
(PUCHAR)Peb->ProcessParameters->Environment);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Simply ignore the exception */
+ }
+ _SEH2_END;
+
+ /* Finalize and copy the MD4 hash */
+ MD4Final(&Md4Context);
+ RtlCopyMemory(&EntropyData->EnvironmentHash, Md4Context.digest, 16);
+ }
+
+ /* Read some machine specific hardware counters */
+ KsecReadMachineSpecificCounters(&EntropyData->MachineSpecificCounters);
+
+ /* Query processor performance information */
+ Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
+
&EntropyData->SystemProcessorPerformanceInformation,
+ sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Query system performance information */
+ Status = ZwQuerySystemInformation(SystemPerformanceInformation,
+ &EntropyData->SystemPerformanceInformation,
+ sizeof(SYSTEM_PERFORMANCE_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Query exception information */
+ Status = ZwQuerySystemInformation(SystemExceptionInformation,
+ &EntropyData->SystemExceptionInformation,
+ sizeof(SYSTEM_EXCEPTION_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Query lookaside information */
+ Status = ZwQuerySystemInformation(SystemLookasideInformation,
+ &EntropyData->SystemLookasideInformation,
+ sizeof(SYSTEM_LOOKASIDE_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Query interrupt information */
+ Status = ZwQuerySystemInformation(SystemInterruptInformation,
+ &EntropyData->SystemInterruptInformation,
+ sizeof(SYSTEM_INTERRUPT_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Query process information */
+ Status = ZwQuerySystemInformation(SystemProcessInformation,
+ &EntropyData->SystemProcessInformation,
+ sizeof(SYSTEM_PROCESS_INFORMATION),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}