2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Drivers
4 * PURPOSE: Kernel Security Support Provider Interface Driver
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
9 /* INCLUDES *******************************************************************/
12 #include <ndk/exfuncs.h>
13 #include <ndk/kefuncs.h>
14 #include <pseh/pseh2.h>
21 /* GLOBALS ********************************************************************/
23 static ULONG KsecRandomSeed
= 0x62b409a1;
26 /* FUNCTIONS ******************************************************************/
34 LARGE_INTEGER TickCount
;
38 /* Try to generate a more random seed */
39 KeQueryTickCount(&TickCount
);
40 KsecRandomSeed
^= _rotl(TickCount
.LowPart
, (KsecRandomSeed
% 23));
43 for (i
= 0; i
< Length
/ sizeof(ULONG
); i
++)
45 P
[i
] = RtlRandomEx(&KsecRandomSeed
);
48 Length
&= (sizeof(ULONG
) - 1);
51 RandomValue
= RtlRandomEx(&KsecRandomSeed
);
52 RtlCopyMemory(&P
[i
], &RandomValue
, Length
);
55 return STATUS_SUCCESS
;
60 KsecReadMachineSpecificCounters(
61 _Out_ PKSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters
)
63 #if defined(_M_IX86) || defined(_M_AMD64)
64 /* Check if RDTSC is available */
65 if (ExIsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE
))
67 /* Read the TSC value */
68 MachineSpecificCounters
->Tsc
= __rdtsc();
71 /* Read the CPU event counter MSRs */
72 MachineSpecificCounters
->Ctr0
= __readmsr(0x12);
73 MachineSpecificCounters
->Ctr1
= __readmsr(0x13);
75 /* Check if this is an MMX capable CPU */
76 if (ExIsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE
))
78 /* Read the CPU performance counters 0 and 1 */
79 MachineSpecificCounters
->Pmc0
= __readpmc(0);
80 MachineSpecificCounters
->Pmc1
= __readpmc(1);
88 * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
92 KsecGatherEntropyData(
93 PKSEC_ENTROPY_DATA EntropyData
)
102 /* Query some generic values */
103 EntropyData
->CurrentProcessId
= PsGetCurrentProcessId();
104 EntropyData
->CurrentThreadId
= PsGetCurrentThreadId();
105 KeQueryTickCount(&EntropyData
->TickCount
);
106 KeQuerySystemTime(&EntropyData
->SystemTime
);
107 EntropyData
->PerformanceCounter
= KeQueryPerformanceCounter(
108 &EntropyData
->PerformanceFrequency
);
110 /* Check if we have a TEB/PEB for the process environment */
111 Teb
= PsGetCurrentThread()->Tcb
.Teb
;
114 Peb
= Teb
->ProcessEnvironmentBlock
;
116 /* Initialize the MD4 context */
117 MD4Init(&Md4Context
);
120 /* Get the end of the environment */
121 String
= Peb
->ProcessParameters
->Environment
;
124 String
+= wcslen(String
) + 1;
127 /* Update the MD4 context from the environment data */
128 MD4Update(&Md4Context
,
129 (PUCHAR
)Peb
->ProcessParameters
->Environment
,
130 (ULONG
)((PUCHAR
)String
- (PUCHAR
)Peb
->ProcessParameters
->Environment
));
132 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
134 /* Simply ignore the exception */
138 /* Finalize and copy the MD4 hash */
139 MD4Final(&Md4Context
);
140 RtlCopyMemory(&EntropyData
->EnvironmentHash
, Md4Context
.digest
, 16);
143 /* Read some machine specific hardware counters */
144 KsecReadMachineSpecificCounters(&EntropyData
->MachineSpecificCounters
);
146 /* Query processor performance information */
147 Status
= ZwQuerySystemInformation(SystemProcessorPerformanceInformation
,
148 &EntropyData
->SystemProcessorPerformanceInformation
,
149 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
),
151 if (!NT_SUCCESS(Status
))
156 /* Query system performance information */
157 Status
= ZwQuerySystemInformation(SystemPerformanceInformation
,
158 &EntropyData
->SystemPerformanceInformation
,
159 sizeof(SYSTEM_PERFORMANCE_INFORMATION
),
161 if (!NT_SUCCESS(Status
))
166 /* Query exception information */
167 Status
= ZwQuerySystemInformation(SystemExceptionInformation
,
168 &EntropyData
->SystemExceptionInformation
,
169 sizeof(SYSTEM_EXCEPTION_INFORMATION
),
171 if (!NT_SUCCESS(Status
))
176 /* Query lookaside information */
177 Status
= ZwQuerySystemInformation(SystemLookasideInformation
,
178 &EntropyData
->SystemLookasideInformation
,
179 sizeof(SYSTEM_LOOKASIDE_INFORMATION
),
181 if (!NT_SUCCESS(Status
))
186 /* Query interrupt information */
187 Status
= ZwQuerySystemInformation(SystemInterruptInformation
,
188 &EntropyData
->SystemInterruptInformation
,
189 sizeof(SYSTEM_INTERRUPT_INFORMATION
),
191 if (!NT_SUCCESS(Status
))
196 /* Query process information */
197 Status
= ZwQuerySystemInformation(SystemProcessInformation
,
198 &EntropyData
->SystemProcessInformation
,
199 sizeof(SYSTEM_PROCESS_INFORMATION
),
201 if (!NT_SUCCESS(Status
))
206 return STATUS_SUCCESS
;