1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Drivers 4 * PURPOSE: Kernel Security Support Provider Interface Driver 5 * 6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "ksecdd.h" 12 13 #define NDEBUG 14 #include <debug.h> 15 16 17 /* GLOBALS ********************************************************************/ 18 19 static ULONG KsecRandomSeed = 0x62b409a1; 20 21 22 /* FUNCTIONS ******************************************************************/ 23 24 NTSTATUS 25 NTAPI 26 KsecGenRandom( 27 PVOID Buffer, 28 SIZE_T Length) 29 { 30 LARGE_INTEGER TickCount; 31 ULONG i, RandomValue; 32 PULONG P; 33 34 /* Try to generate a more random seed */ 35 KeQueryTickCount(&TickCount); 36 KsecRandomSeed ^= _rotl(TickCount.LowPart, (KsecRandomSeed % 23)); 37 38 P = Buffer; 39 for (i = 0; i < Length / sizeof(ULONG); i++) 40 { 41 P[i] = RtlRandomEx(&KsecRandomSeed); 42 } 43 44 Length &= (sizeof(ULONG) - 1); 45 if (Length > 0) 46 { 47 RandomValue = RtlRandomEx(&KsecRandomSeed); 48 RtlCopyMemory(&P[i], &RandomValue, Length); 49 } 50 51 return STATUS_SUCCESS; 52 } 53 54 VOID 55 NTAPI 56 KsecReadMachineSpecificCounters( 57 _Out_ PKSEC_MACHINE_SPECIFIC_COUNTERS MachineSpecificCounters) 58 { 59 #if defined(_M_IX86) || defined(_M_AMD64) 60 /* Check if RDTSC is available */ 61 if (ExIsProcessorFeaturePresent(PF_RDTSC_INSTRUCTION_AVAILABLE)) 62 { 63 /* Read the TSC value */ 64 MachineSpecificCounters->Tsc = __rdtsc(); 65 } 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); 70 71 /* Check if this is an MMX capable CPU */ 72 if (ExIsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE)) 73 { 74 /* Read the CPU performance counters 0 and 1 */ 75 MachineSpecificCounters->Pmc0 = __readpmc(0); 76 MachineSpecificCounters->Pmc1 = __readpmc(1); 77 } 78 #endif 79 #elif defined(_M_ARM) 80 /* Read the Cycle Counter Register */ 81 MachineSpecificCounters->Ccr = _MoveFromCoprocessor(CP15_PMCCNTR); 82 #else 83 #error Implement me! 84 #endif 85 } 86 87 /*! 88 * \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx 89 */ 90 NTSTATUS 91 NTAPI 92 KsecGatherEntropyData( 93 PKSEC_ENTROPY_DATA EntropyData) 94 { 95 MD4_CTX Md4Context; 96 PTEB Teb; 97 PPEB Peb; 98 PWSTR String; 99 ULONG ReturnLength; 100 NTSTATUS Status; 101 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); 109 110 /* Check if we have a TEB/PEB for the process environment */ 111 Teb = PsGetCurrentThread()->Tcb.Teb; 112 if (Teb != NULL) 113 { 114 Peb = Teb->ProcessEnvironmentBlock; 115 116 /* Initialize the MD4 context */ 117 MD4Init(&Md4Context); 118 _SEH2_TRY 119 { 120 /* Get the end of the environment */ 121 String = Peb->ProcessParameters->Environment; 122 while (*String) 123 { 124 String += wcslen(String) + 1; 125 } 126 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)); 131 } 132 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 133 { 134 /* Simply ignore the exception */ 135 } 136 _SEH2_END; 137 138 /* Finalize and copy the MD4 hash */ 139 MD4Final(&Md4Context); 140 RtlCopyMemory(&EntropyData->EnvironmentHash, Md4Context.digest, 16); 141 } 142 143 /* Read some machine specific hardware counters */ 144 KsecReadMachineSpecificCounters(&EntropyData->MachineSpecificCounters); 145 146 /* Query processor performance information */ 147 Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation, 148 &EntropyData->SystemProcessorPerformanceInformation, 149 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), 150 &ReturnLength); 151 if (!NT_SUCCESS(Status)) 152 { 153 return Status; 154 } 155 156 /* Query system performance information */ 157 Status = ZwQuerySystemInformation(SystemPerformanceInformation, 158 &EntropyData->SystemPerformanceInformation, 159 sizeof(SYSTEM_PERFORMANCE_INFORMATION), 160 &ReturnLength); 161 if (!NT_SUCCESS(Status)) 162 { 163 return Status; 164 } 165 166 /* Query exception information */ 167 Status = ZwQuerySystemInformation(SystemExceptionInformation, 168 &EntropyData->SystemExceptionInformation, 169 sizeof(SYSTEM_EXCEPTION_INFORMATION), 170 &ReturnLength); 171 if (!NT_SUCCESS(Status)) 172 { 173 return Status; 174 } 175 176 /* Query lookaside information */ 177 Status = ZwQuerySystemInformation(SystemLookasideInformation, 178 &EntropyData->SystemLookasideInformation, 179 sizeof(SYSTEM_LOOKASIDE_INFORMATION), 180 &ReturnLength); 181 if (!NT_SUCCESS(Status)) 182 { 183 return Status; 184 } 185 186 /* Query interrupt information */ 187 Status = ZwQuerySystemInformation(SystemInterruptInformation, 188 &EntropyData->SystemInterruptInformation, 189 sizeof(SYSTEM_INTERRUPT_INFORMATION), 190 &ReturnLength); 191 if (!NT_SUCCESS(Status)) 192 { 193 return Status; 194 } 195 196 /* Query process information */ 197 Status = ZwQuerySystemInformation(SystemProcessInformation, 198 &EntropyData->SystemProcessInformation, 199 sizeof(SYSTEM_PROCESS_INFORMATION), 200 &ReturnLength); 201 if (!NT_SUCCESS(Status)) 202 { 203 return Status; 204 } 205 206 return STATUS_SUCCESS; 207 } 208