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 *******************************************************************/
17 /* GLOBALS ********************************************************************/
19 static ULONG KsecRandomSeed
= 0x62b409a1;
22 /* FUNCTIONS ******************************************************************/
30 LARGE_INTEGER TickCount
;
34 /* Try to generate a more random seed */
35 KeQueryTickCount(&TickCount
);
36 KsecRandomSeed
^= _rotl(TickCount
.LowPart
, (KsecRandomSeed
% 23));
39 for (i
= 0; i
< Length
/ sizeof(ULONG
); i
++)
41 P
[i
] = RtlRandomEx(&KsecRandomSeed
);
44 Length
&= (sizeof(ULONG
) - 1);
47 RandomValue
= RtlRandomEx(&KsecRandomSeed
);
48 RtlCopyMemory(&P
[i
], &RandomValue
, Length
);
51 return STATUS_SUCCESS
;
56 KsecReadMachineSpecificCounters(
57 _Out_ PKSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters
)
59 #if defined(_M_IX86) || defined(_M_AMD64)
60 /* Check if RDTSC is available */
61 if (ExIsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE
))
63 /* Read the TSC value */
64 MachineSpecificCounters
->Tsc
= __rdtsc();
67 /* Read the CPU event counter MSRs */
68 //MachineSpecificCounters->Ctr0 = __readmsr(0x12);
69 //MachineSpecificCounters->Ctr1 = __readmsr(0x13);
71 /* Check if this is an MMX capable CPU */
72 if (ExIsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE
))
74 /* Read the CPU performance counters 0 and 1 */
75 MachineSpecificCounters
->Pmc0
= __readpmc(0);
76 MachineSpecificCounters
->Pmc1
= __readpmc(1);
84 * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
88 KsecGatherEntropyData(
89 PKSEC_ENTROPY_DATA EntropyData
)
98 /* Query some generic values */
99 EntropyData
->CurrentProcessId
= PsGetCurrentProcessId();
100 EntropyData
->CurrentThreadId
= PsGetCurrentThreadId();
101 KeQueryTickCount(&EntropyData
->TickCount
);
102 KeQuerySystemTime(&EntropyData
->SystemTime
);
103 EntropyData
->PerformanceCounter
= KeQueryPerformanceCounter(
104 &EntropyData
->PerformanceFrequency
);
106 /* Check if we have a TEB/PEB for the process environment */
107 Teb
= PsGetCurrentThread()->Tcb
.Teb
;
110 Peb
= Teb
->ProcessEnvironmentBlock
;
112 /* Initialize the MD4 context */
113 MD4Init(&Md4Context
);
116 /* Get the end of the environment */
117 String
= Peb
->ProcessParameters
->Environment
;
120 String
+= wcslen(String
) + 1;
123 /* Update the MD4 context from the environment data */
124 MD4Update(&Md4Context
,
125 (PUCHAR
)Peb
->ProcessParameters
->Environment
,
126 (ULONG
)((PUCHAR
)String
- (PUCHAR
)Peb
->ProcessParameters
->Environment
));
128 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
130 /* Simply ignore the exception */
134 /* Finalize and copy the MD4 hash */
135 MD4Final(&Md4Context
);
136 RtlCopyMemory(&EntropyData
->EnvironmentHash
, Md4Context
.digest
, 16);
139 /* Read some machine specific hardware counters */
140 KsecReadMachineSpecificCounters(&EntropyData
->MachineSpecificCounters
);
142 /* Query processor performance information */
143 Status
= ZwQuerySystemInformation(SystemProcessorPerformanceInformation
,
144 &EntropyData
->SystemProcessorPerformanceInformation
,
145 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
),
147 if (!NT_SUCCESS(Status
))
152 /* Query system performance information */
153 Status
= ZwQuerySystemInformation(SystemPerformanceInformation
,
154 &EntropyData
->SystemPerformanceInformation
,
155 sizeof(SYSTEM_PERFORMANCE_INFORMATION
),
157 if (!NT_SUCCESS(Status
))
162 /* Query exception information */
163 Status
= ZwQuerySystemInformation(SystemExceptionInformation
,
164 &EntropyData
->SystemExceptionInformation
,
165 sizeof(SYSTEM_EXCEPTION_INFORMATION
),
167 if (!NT_SUCCESS(Status
))
172 /* Query lookaside information */
173 Status
= ZwQuerySystemInformation(SystemLookasideInformation
,
174 &EntropyData
->SystemLookasideInformation
,
175 sizeof(SYSTEM_LOOKASIDE_INFORMATION
),
177 if (!NT_SUCCESS(Status
))
182 /* Query interrupt information */
183 Status
= ZwQuerySystemInformation(SystemInterruptInformation
,
184 &EntropyData
->SystemInterruptInformation
,
185 sizeof(SYSTEM_INTERRUPT_INFORMATION
),
187 if (!NT_SUCCESS(Status
))
192 /* Query process information */
193 Status
= ZwQuerySystemInformation(SystemProcessInformation
,
194 &EntropyData
->SystemProcessInformation
,
195 sizeof(SYSTEM_PROCESS_INFORMATION
),
197 if (!NT_SUCCESS(Status
))
202 return STATUS_SUCCESS
;