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/CMake... ============================================================================== --- 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/dispa... ============================================================================== --- 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/ksecd... ============================================================================== --- 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/rando... ============================================================================== --- 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; +}