mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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 svn path=/trunk/; revision=61842
This commit is contained in:
parent
ae7c4bf21d
commit
518460d44c
4 changed files with 193 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue