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();
66 #if 0 // FIXME: investigate what the requirements are for these
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);
80 /* FIXME: this should go into a public header (from ksarm.h) */
81 #define CP15_PMCCNTR 15, 0, 9, 13, 0
82 /* Read the Cycle Counter Register */
83 MachineSpecificCounters
->Ccr
= _MoveFromCoprocessor(CP15_PMCCNTR
);
90 * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
94 KsecGatherEntropyData(
95 PKSEC_ENTROPY_DATA EntropyData
)
104 /* Query some generic values */
105 EntropyData
->CurrentProcessId
= PsGetCurrentProcessId();
106 EntropyData
->CurrentThreadId
= PsGetCurrentThreadId();
107 KeQueryTickCount(&EntropyData
->TickCount
);
108 KeQuerySystemTime(&EntropyData
->SystemTime
);
109 EntropyData
->PerformanceCounter
= KeQueryPerformanceCounter(
110 &EntropyData
->PerformanceFrequency
);
112 /* Check if we have a TEB/PEB for the process environment */
113 Teb
= PsGetCurrentThread()->Tcb
.Teb
;
116 Peb
= Teb
->ProcessEnvironmentBlock
;
118 /* Initialize the MD4 context */
119 MD4Init(&Md4Context
);
122 /* Get the end of the environment */
123 String
= Peb
->ProcessParameters
->Environment
;
126 String
+= wcslen(String
) + 1;
129 /* Update the MD4 context from the environment data */
130 MD4Update(&Md4Context
,
131 (PUCHAR
)Peb
->ProcessParameters
->Environment
,
132 (ULONG
)((PUCHAR
)String
- (PUCHAR
)Peb
->ProcessParameters
->Environment
));
134 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
136 /* Simply ignore the exception */
140 /* Finalize and copy the MD4 hash */
141 MD4Final(&Md4Context
);
142 RtlCopyMemory(&EntropyData
->EnvironmentHash
, Md4Context
.digest
, 16);
145 /* Read some machine specific hardware counters */
146 KsecReadMachineSpecificCounters(&EntropyData
->MachineSpecificCounters
);
148 /* Query processor performance information */
149 Status
= ZwQuerySystemInformation(SystemProcessorPerformanceInformation
,
150 &EntropyData
->SystemProcessorPerformanceInformation
,
151 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
),
153 if (!NT_SUCCESS(Status
))
158 /* Query system performance information */
159 Status
= ZwQuerySystemInformation(SystemPerformanceInformation
,
160 &EntropyData
->SystemPerformanceInformation
,
161 sizeof(SYSTEM_PERFORMANCE_INFORMATION
),
163 if (!NT_SUCCESS(Status
))
168 /* Query exception information */
169 Status
= ZwQuerySystemInformation(SystemExceptionInformation
,
170 &EntropyData
->SystemExceptionInformation
,
171 sizeof(SYSTEM_EXCEPTION_INFORMATION
),
173 if (!NT_SUCCESS(Status
))
178 /* Query lookaside information */
179 Status
= ZwQuerySystemInformation(SystemLookasideInformation
,
180 &EntropyData
->SystemLookasideInformation
,
181 sizeof(SYSTEM_LOOKASIDE_INFORMATION
),
183 if (!NT_SUCCESS(Status
))
188 /* Query interrupt information */
189 Status
= ZwQuerySystemInformation(SystemInterruptInformation
,
190 &EntropyData
->SystemInterruptInformation
,
191 sizeof(SYSTEM_INTERRUPT_INFORMATION
),
193 if (!NT_SUCCESS(Status
))
198 /* Query process information */
199 Status
= ZwQuerySystemInformation(SystemProcessInformation
,
200 &EntropyData
->SystemProcessInformation
,
201 sizeof(SYSTEM_PROCESS_INFORMATION
),
203 if (!NT_SUCCESS(Status
))
208 return STATUS_SUCCESS
;