mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
3.9 KiB
181 lines
3.9 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
|
//
|
|
// File: rng.c
|
|
//
|
|
// Contents:
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 8-15-95 RichardW Created
|
|
// 2-8-96 MikeSw Copied to NTLMSSP from SSL
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <ntlmcomn.h> // Include files common to Serice and DLL
|
|
#include <ntlmsspi.h> // Data private to the common routines
|
|
#include <rc4.h>
|
|
|
|
|
|
#define RNG_BITS 64
|
|
#define RNG_BYTES_PER_BATCH 768
|
|
|
|
typedef struct _SourceBits {
|
|
ULONG Valid;
|
|
BYTE Bits[RNG_BITS];
|
|
} SourceBits, * PSourceBits;
|
|
|
|
typedef struct _RNG_State {
|
|
RTL_CRITICAL_SECTION csLock;
|
|
LONG Available;
|
|
struct RC4_KEYSTRUCT key;
|
|
} RNG_State;
|
|
|
|
|
|
|
|
#define SEED_ARRAY_SIZE 16
|
|
|
|
|
|
RNG_State SspRNG;
|
|
|
|
#define LockRNG(r) EnterCriticalSection( &r.csLock )
|
|
#define UnlockRNG(r) LeaveCriticalSection( &r.csLock )
|
|
|
|
|
|
#define ADD_BYTE(p, x) \
|
|
((PSourceBits) p)->Bits[ ((PSourceBits) p)->Valid++ ] = x; \
|
|
if (((PSourceBits) p)->Valid >= RNG_BITS ) \
|
|
{ \
|
|
goto SystemData_Exit; \
|
|
}
|
|
|
|
VOID
|
|
SspGetSystemData(
|
|
PSourceBits pBits
|
|
)
|
|
{
|
|
LARGE_INTEGER liPerf;
|
|
SYSTEMTIME SystemTime;
|
|
MEMORYSTATUS Mem;
|
|
DWORD i;
|
|
|
|
|
|
GetLocalTime(&SystemTime);
|
|
|
|
ADD_BYTE(pBits, LOBYTE( SystemTime.wMilliseconds ) );
|
|
|
|
ADD_BYTE(pBits, HIBYTE( SystemTime.wMilliseconds ) );
|
|
|
|
ADD_BYTE(pBits, LOBYTE( SystemTime.wSecond ) ^ LOBYTE( SystemTime.wMinute ) );
|
|
|
|
if (QueryPerformanceCounter(&liPerf))
|
|
{
|
|
ADD_BYTE(pBits, LOBYTE( LOWORD( liPerf.LowPart ) ) ^ LOBYTE( LOWORD( liPerf.HighPart ) ) );
|
|
ADD_BYTE(pBits, HIBYTE( LOWORD( liPerf.LowPart ) ) ^ LOBYTE( LOWORD( liPerf.HighPart ) ) );
|
|
ADD_BYTE(pBits, LOBYTE( HIWORD( liPerf.LowPart ) ) ^ LOBYTE( LOWORD( liPerf.HighPart ) ) );
|
|
ADD_BYTE(pBits, HIBYTE( HIWORD( liPerf.LowPart ) ) ^ LOBYTE( LOWORD( liPerf.HighPart ) ) );
|
|
}
|
|
|
|
GlobalMemoryStatus( &Mem );
|
|
|
|
ADD_BYTE(pBits, LOBYTE( HIWORD( Mem.dwAvailPhys ) ) );
|
|
ADD_BYTE(pBits, HIBYTE( HIWORD( Mem.dwAvailPhys ) ) );
|
|
ADD_BYTE(pBits, LOBYTE( HIWORD( Mem.dwAvailPageFile ) ) );
|
|
ADD_BYTE(pBits, HIBYTE( HIWORD( Mem.dwAvailPageFile ) ) );
|
|
ADD_BYTE(pBits, LOBYTE( HIWORD( Mem.dwAvailVirtual ) ) );
|
|
|
|
//
|
|
// TODO: Add other things, like cache manager, heap frag, etc.
|
|
//
|
|
|
|
SystemData_Exit:
|
|
|
|
for (i = 0 ; i < pBits->Valid ; i++ )
|
|
{
|
|
pBits->Bits[ i ] ^= pBits->Bits[ pBits->Valid - i ];
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
SspGenerateRandomBits(
|
|
PUCHAR pRandomData,
|
|
LONG cRandomData
|
|
)
|
|
{
|
|
LONG i;
|
|
DWORD Bytes;
|
|
SourceBits Bits;
|
|
|
|
ZeroMemory( pRandomData, cRandomData );
|
|
|
|
LockRNG( SspRNG );
|
|
|
|
if (cRandomData > SspRNG.Available)
|
|
{
|
|
Bytes = SspRNG.Available;
|
|
}
|
|
else
|
|
{
|
|
Bytes = cRandomData;
|
|
}
|
|
|
|
cRandomData -= Bytes;
|
|
|
|
if (Bytes)
|
|
{
|
|
rc4( &SspRNG.key, Bytes, pRandomData );
|
|
|
|
SspRNG.Available -= Bytes;
|
|
}
|
|
|
|
if (cRandomData)
|
|
{
|
|
pRandomData += Bytes;
|
|
|
|
Bits.Valid = 0;
|
|
|
|
SspGetSystemData( &Bits );
|
|
|
|
ZeroMemory( &SspRNG.key, sizeof( SspRNG.key ) );
|
|
|
|
rc4_key( &SspRNG.key, Bits.Valid, Bits.Bits );
|
|
|
|
rc4( &SspRNG.key, cRandomData, pRandomData );
|
|
|
|
SspRNG.Available = RNG_BYTES_PER_BATCH - cRandomData ;
|
|
|
|
if (SspRNG.Available < 0)
|
|
{
|
|
SspRNG.Available = 0;
|
|
}
|
|
|
|
}
|
|
|
|
UnlockRNG( SspRNG );
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
SspInitializeRNG(VOID)
|
|
{
|
|
InitializeCriticalSection( &SspRNG.csLock );
|
|
|
|
LockRNG( SspRNG );
|
|
|
|
SspRNG.Available = 0;
|
|
|
|
UnlockRNG( SspRNG );
|
|
|
|
}
|
|
|
|
VOID
|
|
SspCleanupRNG(VOID)
|
|
{
|
|
DeleteCriticalSection(&SspRNG.csLock);
|
|
}
|