⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rndwin32.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*																			*
*						  Win32 Randomness-Gathering Code					*
*	Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2003	*
*																			*
****************************************************************************/

/* This module is part of the cryptlib continuously seeded pseudorandom number
   generator.  For usage conditions, see dev_sys.c.

   From the "Peter giveth and Microsoft taketh away" department: The default
   NT setup has Everyone:Read permissions for the
   \\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\PerfLib
   key, which is the key for the performance counters.  This means that
   everyone on the network can read your machine's performance counters,
   significantly reducing their usefulness (although since they only contain 
   a snapshot, network users should never see exactly what you're seeing).  
   If you're worried about the native API call that's normally used failing 
   (which falls back to using the registry performance counters), delete the 
   Everyone:Read ACL and replace it with Interactive:Read, which only allows 
   access to locally logged on users.  This means that an attacker will have 
   to go to the effort of planting a trojan to get your crypto keys rather 
   than getting them over the net.

   "Windows NT is a thing of genuine beauty, if you're seriously into genuine
	ugliness.  It's like a woman with a history of insanity in the family,
	only worse" -- Hans Chloride, "Why I Love Windows NT" */

/* General includes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef INC_CHILD
  #include "../crypt.h"
#else
  #include "crypt.h"
#endif /* Compiler-specific includes */

/* OS-specific includes */

#include <tlhelp32.h>
#include <winperf.h>
#include <winioctl.h>
#include <process.h>

/* Some new CPU opcodes aren't supported by all compiler versions, if 
   they're not available we define them here */

#if defined( _MSC_VER ) && ( _MSC_VER <= 1100 )
  #define cpuid		__asm _emit 0x0F __asm _emit 0xA2
  #define rdtsc		__asm _emit 0x0F __asm _emit 0x31
#endif /* VC++ 5.0 or earlier */
#define xstore_rng	__asm _emit 0x0F __asm _emit 0xA7 __asm _emit 0xC0

/* The size of the intermediate buffer used to accumulate polled data */

#define RANDOM_BUFSIZE	4096

/* When we're running a background poll, the main thread can ask it to
   terminate if cryptlib is shutting down.  The following macro checks
   whether the background thread should exit prematurely */

#define checkPollExit()	\
		{ \
		BOOLEAN exitFlag; \
		\
		enterMutex( MUTEX_RANDOMPOLLING ); \
		exitFlag = exitNow; \
		exitMutex( MUTEX_RANDOMPOLLING ); \
		if( exitFlag ) \
			return; \
		}

/* A flag telling the randomness polling thread to exit.  This is set on
   shutdown to indicate that it should bail out as quickly as possible so as
   not to hold up the shutdown */

static BOOLEAN exitNow;

/* Handles to various randomness objects */

static HANDLE hAdvAPI32;	/* Handle to misc.library */
static HANDLE hNetAPI32;	/* Handle to networking library */
static HANDLE hNTAPI;		/* Handle to NT kernel library */
static HANDLE hThread;		/* Background polling thread handle */
static DWORD threadID;		/* Background polling thread ID */

/****************************************************************************
*																			*
*							Misc Randomness Sources							*
*																			*
****************************************************************************/

/* The number of bytes to read from the PIII RNG on each slow poll */

#define PIIIRNG_BYTES		64

/* Intel Chipset CSP type and name */

#define PROV_INTEL_SEC	22
#define INTEL_DEF_PROV	"Intel Hardware Cryptographic Service Provider"

/* A mapping from CryptoAPI to standard data types */

#define HCRYPTPROV			HANDLE

/* Type definitions for function pointers to call CryptoAPI functions */

typedef BOOL ( WINAPI *CRYPTACQUIRECONTEXT )( HCRYPTPROV *phProv,
											  LPCTSTR pszContainer,
											  LPCTSTR pszProvider, DWORD dwProvType,
											  DWORD dwFlags );
typedef BOOL ( WINAPI *CRYPTGENRANDOM )( HCRYPTPROV hProv, DWORD dwLen,
										 BYTE *pbBuffer );
typedef BOOL ( WINAPI *CRYPTRELEASECONTEXT )( HCRYPTPROV hProv, DWORD dwFlags );

/* Global function pointers. These are necessary because the functions need
   to be dynamically linked since older versions of Win95 and NT don't contain
   them */

static CRYPTACQUIRECONTEXT pCryptAcquireContext = NULL;
static CRYPTGENRANDOM pCryptGenRandom = NULL;
static CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;

/* Handle to the RNG CSP */

static HCRYPTPROV hProv;	/* Handle to Intel RNG CSP */

/* Try and connect to the PIII RNG CSP.  The AMD 768 southbridge (from the 
   760 MP chipset) also has a hardware RNG, but there doesn't appear to be 
   any driver support for this as there is for the Intel RNG so we can't do
   much with it */

static void initPIIIRng( void )
	{
	hProv = NULL;
	if( ( hAdvAPI32 = GetModuleHandle( "AdvAPI32.dll" ) ) == NULL )
		return;

	/* Get pointers to the CSP functions.  Although the acquire context 
	   function looks like a standard function, it's actually a macro which 
	   is mapped to (depending on the build type) CryptAcquireContextA or 
	   CryptAcquireContextW, so we access it under the straight-ASCII-
	   function name */
	pCryptAcquireContext = ( CRYPTACQUIRECONTEXT ) GetProcAddress( hAdvAPI32,
													"CryptAcquireContextA" );
	pCryptGenRandom = ( CRYPTGENRANDOM ) GetProcAddress( hAdvAPI32,
													"CryptGenRandom" );
	pCryptReleaseContext = ( CRYPTRELEASECONTEXT ) GetProcAddress( hAdvAPI32,
													"CryptReleaseContext" );

	/* Make sure we got valid pointers for every CryptoAPI function and that 
	   the required CSP is present */
	if( pCryptAcquireContext == NULL || \
		pCryptGenRandom == NULL || pCryptReleaseContext == NULL || \
		pCryptAcquireContext( &hProv, NULL, INTEL_DEF_PROV,
							  PROV_INTEL_SEC, 0 ) == FALSE )
		{
		hAdvAPI32 = NULL;
		hProv = NULL;
		}
	}

/* Read data from the PIII hardware RNG */

static void readPIIIRng( void )
	{
	BYTE buffer[ PIIIRNG_BYTES ];

	if( hProv == NULL )
		return;

	/* Read 128 bytes from the PIII RNG.  We don't rely on this for all our 
	   randomness requirements in case it's broken in some way */
	if( pCryptGenRandom( hProv, PIIIRNG_BYTES, buffer ) )
		{
		RESOURCE_DATA msgData;
		static const int quality = 90;

		setMessageData( &msgData, buffer, PIIIRNG_BYTES );
		krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE_S, 
						 &msgData, CRYPT_IATTRIBUTE_ENTROPY );
		krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE, 
						 ( void * ) &quality, 
						 CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
		zeroise( buffer, PIIIRNG_BYTES );
		}
	}

/* MBM data structures, originally by Alexander van Kaam, converted to C by 
   Anders@Majland.org, finally updated by Chris Zahrt <techn0@iastate.edu> */

#define BusType		char
#define SMBType		char
#define SensorType	char

typedef struct {
	SensorType iType;			/* Type of sensor */
	int Count;					/* Number of sensor for that type */
	} SharedIndex;

typedef struct {
	SensorType ssType;			/* Type of sensor */
	unsigned char ssName[ 12 ];	/* Name of sensor */
	char sspadding1[ 3 ];		/* Padding of 3 bytes */
	double ssCurrent;			/* Current value */
	double ssLow;				/* Lowest readout */
	double ssHigh;				/* Highest readout */
	long ssCount;				/* Total number of readout */
	char sspadding2[ 4 ];		/* Padding of 4 bytes */
	long double ssTotal;		/* Total amout of all readouts */
	char sspadding3[ 6 ];		/* Padding of 6 bytes */
	double ssAlarm1;			/* Temp & fan: high alarm; voltage: % off */
	double ssAlarm2;			/* Temp: low alarm */
	} SharedSensor;

typedef struct {
	short siSMB_Base;			/* SMBus base address */
	BusType siSMB_Type;			/* SMBus/Isa bus used to access chip */
	SMBType siSMB_Code;			/* SMBus sub type, Intel, AMD or ALi */
	char siSMB_Addr;			/* Address of sensor chip on SMBus */
	unsigned char siSMB_Name[ 41 ];	/* Nice name for SMBus */
	short siISA_Base;			/* ISA base address of sensor chip on ISA */
	int siChipType;				/* Chip nr, connects with Chipinfo.ini */
	char siVoltageSubType;		/* Subvoltage option selected */
	} SharedInfo;

typedef struct {
	double sdVersion;			/* Version number (example: 51090) */
	SharedIndex sdIndex[ 10 ];	/* Sensor index */
	SharedSensor sdSensor[ 100 ];	/* Sensor info */
	SharedInfo sdInfo;			/* Misc.info */
	unsigned char sdStart[ 41 ];	/* Start time */
	/* We don't use the next two fields both because they're not random and 
	   because it provides a nice safety margin in case of data size mis-
	   estimates (we always under-estimate the buffer size) */
/*	unsigned char sdCurrent[ 41 ];	/* Current time */
/*	unsigned char sdPath[ 256 ];	/* MBM path */
	} SharedData;

/* Read data from MBM.  This communicates via shared memory, so all we need 
   to do is map a file and read the data out */

static void readMBMData( void )
	{
	HANDLE hMBMData;
	SharedData *mbmDataPtr;

	if( ( hMBMData = OpenFileMapping( FILE_MAP_READ, FALSE, 
									  "$M$B$M$5$S$D$" ) ) != NULL )
		{
		if( ( mbmDataPtr = ( SharedData * ) \
				MapViewOfFile( hMBMData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
			{
			RESOURCE_DATA msgData;
			static const int quality = 20;

			setMessageData( &msgData, mbmDataPtr, sizeof( SharedData ) );
			krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE_S, 
							 &msgData, CRYPT_IATTRIBUTE_ENTROPY );
			krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE, 
							 ( void * ) &quality, 
							 CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
			UnmapViewOfFile( mbmDataPtr );
			}
		CloseHandle( hMBMData );
		}
	}

/****************************************************************************
*																			*
*									Fast Poll								*
*																			*
****************************************************************************/

/* The shared Win32 fast poll routine */

void fastPoll( void )
	{
	static BOOLEAN addedFixedItems = FALSE;
	static BOOLEAN hasAdvFeatures = FALSE, hasHardwareRNG = FALSE;
	FILETIME  creationTime, exitTime, kernelTime, userTime;
	DWORD minimumWorkingSetSize, maximumWorkingSetSize;
	LARGE_INTEGER performanceCount;
	MEMORYSTATUS memoryStatus;
	HANDLE handle;
	POINT point;
	RANDOM_STATE randomState;
	BYTE buffer[ RANDOM_BUFSIZE ];
	int bufIndex = 0;

	checkPollExit();

	initRandomData( randomState, buffer, RANDOM_BUFSIZE );

	/* Get various basic pieces of system information: Handle of active
	   window, handle of window with mouse capture, handle of clipboard owner
	   handle of start of clpboard viewer list, pseudohandle of current
	   process, current process ID, pseudohandle of current thread, current
	   thread ID, handle of desktop window, handle  of window with keyboard
	   focus, whether system queue has any events, cursor position for last
	   message, 1 ms time for last message, handle of window with clipboard
	   open, handle of process heap, handle of procs window station, types of
	   events in input queue, and milliseconds since Windows was started */
	addRandomValue( randomState, GetActiveWindow() );
	addRandomValue( randomState, GetCapture() );
	addRandomValue( randomState, GetClipboardOwner() );
	addRandomValue( randomState, GetClipboardViewer() );
	addRandomValue( randomState, GetCurrentProcess() );
	addRandomValue( randomState, GetCurrentProcessId() );
	addRandomValue( randomState, GetCurrentThread() );
	addRandomValue( randomState, GetCurrentThreadId() );
	addRandomValue( randomState, GetDesktopWindow() );
	addRandomValue( randomState, GetFocus() );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -