- 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

svn path=/trunk/; revision=61842
This commit is contained in:
Timo Kreuzer 2014-01-26 20:30:06 +00:00
parent ae7c4bf21d
commit 518460d44c
4 changed files with 193 additions and 1 deletions

View file

@ -1,6 +1,10 @@
spec2def(ksecdd.sys ksecdd.spec)
include_directories(
${REACTOS_SOURCE_DIR}/lib/cryptlib)
list(APPEND SOURCE
ksecdd.c
dispatch.c
@ -9,6 +13,7 @@ list(APPEND SOURCE
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)

View file

@ -60,7 +60,7 @@ KsecQueryVolumeInformation(
PFILE_FS_DEVICE_INFORMATION DeviceInformation;
/* Only FileFsDeviceInformation is supported */
if (FsInformationClass == FileFsDeviceInformation)
if (FsInformationClass != FileFsDeviceInformation)
{
return STATUS_INVALID_INFO_CLASS;
}

View file

@ -8,11 +8,43 @@
#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
KsecDdDispatch(

View file

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