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 ******************************************************************/
37 /* Try to generate a more random seed */
38 KsecRandomSeed
^= _rotl(KeTickCount
.LowPart
, (KsecRandomSeed
% 23));
41 for (i
= 0; i
< Length
/ sizeof(ULONG
); i
++)
43 P
[i
] = RtlRandomEx(&KsecRandomSeed
);
46 Length
&= (sizeof(ULONG
) - 1);
49 RandomValue
= RtlRandomEx(&KsecRandomSeed
);
50 RtlCopyMemory(&P
[i
], &RandomValue
, Length
);
53 return STATUS_SUCCESS
;
58 KsecReadMachineSpecificCounters(
59 _Out_ PKSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters
)
61 #if defined(_M_IX86) || defined(_M_AMD64)
62 /* Check if RDTSC is available */
63 if (ExIsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE
))
65 /* Read the TSC value */
66 MachineSpecificCounters
->Tsc
= __rdtsc();
69 /* Read the CPU event counter MSRs */
70 MachineSpecificCounters
->Ctr0
= __readmsr(0x12);
71 MachineSpecificCounters
->Ctr1
= __readmsr(0x13);
73 /* Check if this is an MMX capable CPU */
74 if (ExIsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE
))
76 /* Read the CPU performance counters 0 and 1 */
77 MachineSpecificCounters
->Pmc0
= __readpmc(0);
78 MachineSpecificCounters
->Pmc1
= __readpmc(1);
86 * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
90 KsecGatherEntropyData(
91 PKSEC_ENTROPY_DATA EntropyData
)
100 /* Query some generic values */
101 EntropyData
->CurrentProcessId
= PsGetCurrentProcessId();
102 EntropyData
->CurrentThreadId
= PsGetCurrentThreadId();
103 KeQueryTickCount(&EntropyData
->TickCount
);
104 KeQuerySystemTime(&EntropyData
->SystemTime
);
105 EntropyData
->PerformanceCounter
= KeQueryPerformanceCounter(
106 &EntropyData
->PerformanceFrequency
);
108 /* Check if we have a TEB/PEB for the process environment */
109 Teb
= PsGetCurrentThread()->Tcb
.Teb
;
112 Peb
= Teb
->ProcessEnvironmentBlock
;
114 /* Initialize the MD4 context */
115 MD4Init(&Md4Context
);
118 /* Get the end of the environment */
119 String
= Peb
->ProcessParameters
->Environment
;
122 String
+= wcslen(String
) + 1;
125 /* Update the MD4 context from the environment data */
126 MD4Update(&Md4Context
,
127 (PUCHAR
)Peb
->ProcessParameters
->Environment
,
128 (PUCHAR
)String
- (PUCHAR
)Peb
->ProcessParameters
->Environment
);
130 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
132 /* Simply ignore the exception */
136 /* Finalize and copy the MD4 hash */
137 MD4Final(&Md4Context
);
138 RtlCopyMemory(&EntropyData
->EnvironmentHash
, Md4Context
.digest
, 16);
141 /* Read some machine specific hardware counters */
142 KsecReadMachineSpecificCounters(&EntropyData
->MachineSpecificCounters
);
144 /* Query processor performance information */
145 Status
= ZwQuerySystemInformation(SystemProcessorPerformanceInformation
,
146 &EntropyData
->SystemProcessorPerformanceInformation
,
147 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
),
149 if (!NT_SUCCESS(Status
))
154 /* Query system performance information */
155 Status
= ZwQuerySystemInformation(SystemPerformanceInformation
,
156 &EntropyData
->SystemPerformanceInformation
,
157 sizeof(SYSTEM_PERFORMANCE_INFORMATION
),
159 if (!NT_SUCCESS(Status
))
164 /* Query exception information */
165 Status
= ZwQuerySystemInformation(SystemExceptionInformation
,
166 &EntropyData
->SystemExceptionInformation
,
167 sizeof(SYSTEM_EXCEPTION_INFORMATION
),
169 if (!NT_SUCCESS(Status
))
174 /* Query lookaside information */
175 Status
= ZwQuerySystemInformation(SystemLookasideInformation
,
176 &EntropyData
->SystemLookasideInformation
,
177 sizeof(SYSTEM_LOOKASIDE_INFORMATION
),
179 if (!NT_SUCCESS(Status
))
184 /* Query interrupt information */
185 Status
= ZwQuerySystemInformation(SystemInterruptInformation
,
186 &EntropyData
->SystemInterruptInformation
,
187 sizeof(SYSTEM_INTERRUPT_INFORMATION
),
189 if (!NT_SUCCESS(Status
))
194 /* Query process information */
195 Status
= ZwQuerySystemInformation(SystemProcessInformation
,
196 &EntropyData
->SystemProcessInformation
,
197 sizeof(SYSTEM_PROCESS_INFORMATION
),
199 if (!NT_SUCCESS(Status
))
204 return STATUS_SUCCESS
;