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

📄 random.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
   This product uses components written by Paul Le Roux <pleroux@swprofessionals.com> */

#include "TCdefs.h"

#include <tlhelp32.h>

#include "crypto.h"
#include "crc.h"
#include "random.h"
#include "apidrvr.h"
#include "dlgcode.h"


/* random management defines & pool pointers */
#define POOLSIZE 256
#define RANDOMPOOL_ALLOCSIZE	( ( POOLSIZE + SHA_DIGESTSIZE - 1 ) \
	/ SHA_DIGESTSIZE ) * SHA_DIGESTSIZE

unsigned char *pRandPool = NULL;
int nRandIndex = 0;

/* Macro to add a single byte to the pool */
#define RandaddByte(x) {\
	if (nRandIndex==POOLSIZE) nRandIndex = 0;\
	pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \
	nRandIndex++; \
	Randmix(); \
	}

/* Macro to add four bytes to the pool */
#define RandaddLong(x) _RandaddLong((unsigned long)x);

#pragma warning( disable : 4710 ) /* inline func. not expanded warning */

_inline void _RandaddLong(unsigned long x)
{
	RandaddByte(x); 
	RandaddByte((x >> 8)); 
	RandaddByte((x >> 16));
	RandaddByte((x >> 24));
}

HHOOK hMouse = NULL;		/* Mouse hook for the random number generator */
HHOOK hKeyboard = NULL;		/* Keyboard hook for the random number
				   generator */

/* Variables for thread control, the thread is used to gather up info about
   the system in in the background */
CRITICAL_SECTION critRandProt;	/* The critical section */
BOOL volatile bThreadTerminate = FALSE;	/* This variable is shared among
					   thread's so its made volatile */
BOOL bDidSlowPoll = FALSE;	/* We do the slow poll only once */

/* Network library handle for the slowPollWinNT function */
HANDLE hNetAPI32 = NULL;

BOOL bRandDidInit = FALSE;

/* Init the random number generator, setup the hooks, and start the thread */
int
Randinit ()
{
	HANDLE threadID;

	if(bRandDidInit == TRUE) return 0;

	InitializeCriticalSection (&critRandProt);

	bRandDidInit = TRUE;

	pRandPool = (unsigned char *) TCalloc (RANDOMPOOL_ALLOCSIZE);
	if (pRandPool == NULL)
		goto error;
	else
		memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE);

	hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ());
	hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ());
	if (hMouse == 0 || hKeyboard == 0)
		goto error;

	threadID = (HANDLE) _beginthread (ThreadSafeThreadFunction, 8192, NULL);
	if (threadID == (HANDLE) - 1)
		goto error;

	return 0;

      error:
	Randfree ();
	return 1;
}

/* Close everything down, including the thread which is closed down by
   setting a flag which eventually causes the thread function to exit */
void
Randfree ()
{
	if (bRandDidInit == FALSE)
		return;

	EnterCriticalSection (&critRandProt);

	if (hMouse != 0)
		UnhookWindowsHookEx (hMouse);
	if (hKeyboard != 0)
		UnhookWindowsHookEx (hKeyboard);

	bThreadTerminate = TRUE;

	LeaveCriticalSection (&critRandProt);

	for (;;)
	{
		Sleep (250);
		EnterCriticalSection (&critRandProt);
		if (bThreadTerminate == FALSE)
		{
			LeaveCriticalSection (&critRandProt);
			break;
		}
		LeaveCriticalSection (&critRandProt);
	}

	if (pRandPool != NULL)
	{
		burn (pRandPool, RANDOMPOOL_ALLOCSIZE);
		TCfree (pRandPool);
		pRandPool = NULL;
	}

	if (hNetAPI32 != 0)
	{
		FreeLibrary (hNetAPI32);
		hNetAPI32 = NULL;
	}

	hMouse = NULL;
	hKeyboard = NULL;
	nRandIndex = 0;
	bThreadTerminate = FALSE;
	DeleteCriticalSection (&critRandProt);
	bRandDidInit = FALSE;
}

/* Mix random pool with the hash function */
void
Randmix ()
{
	int i;

	for (i = 0; i < POOLSIZE; i += SHA_DIGESTSIZE)
	{
		unsigned char inputBuffer[SHA_BLOCKSIZE];
		int j;

		/* Copy SHA_BLOCKSIZE bytes from the circular buffer into the
		   hash data buffer, hash the data, and copy the result back
		   into the random pool */
		for (j = 0; j < SHA_BLOCKSIZE; j++)
			inputBuffer[j] = pRandPool[(i + j) % POOLSIZE];
		SHA1TRANSFORM ((unsigned long *) (pRandPool + i), inputBuffer);
		memset (inputBuffer, 0, SHA_BLOCKSIZE);
	}
}

/* Add a buffer to the pool */
void
RandaddBuf (void *buf, int len)
{
	int i;
	for (i = 0; i < len; i++)
	{
		RandaddByte (((unsigned char *) buf)[i]);
	}
}

void
RandpeekBytes (char *buf, int len)
{
	EnterCriticalSection (&critRandProt);
	memcpy (buf, pRandPool, len);
	LeaveCriticalSection (&critRandProt);
}

/* Get a certain amount of true random bytes from the pool */
void
RandgetBytes (char *buf, int len)
{
	int i;

	EnterCriticalSection (&critRandProt);

	FastPoll ();

	if (bDidSlowPoll == FALSE)
	{
		bDidSlowPoll = TRUE;

#ifndef _DEBUG
		if (nCurrentOS == WIN_NT)
			SlowPollWinNT ();
		else
			SlowPollWin9x ();
#endif
	}
	/* Then mix the pool */
	Randmix ();

	/* There's never more than POOLSIZE worth of randomess */
	if (len > POOLSIZE)
		len = POOLSIZE;

	/* Extract out the random bytes needed */
	memcpy (buf, pRandPool, len);

	/* Now invert the pool */
	for (i = 0; i < POOLSIZE / 4; i++)
	{
		((unsigned long *) pRandPool)[i] = ~((unsigned long *) pRandPool)[i];
	}

	/* Now remix the pool, creating the new pool */
	Randmix ();

	LeaveCriticalSection (&critRandProt);
}

/* Capture the mouse, and as long as the event is not the same as the last
   two events :- add a crc of the event, and a crc of the time difference
   between this event and the last + the current time to the pool */
LRESULT CALLBACK
MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
	static DWORD dwLastTimer;
	static unsigned long lastCrc, lastCrc2;
	MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;

	if (nCode < 0)
		return CallNextHookEx (hMouse, nCode, wParam, lParam);
	else
	{
		DWORD dwTimer = GetTickCount ();
		DWORD j = dwLastTimer - dwTimer;
		unsigned long crc = 0L;
		int i;

		dwLastTimer = dwTimer;

		for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
		{
			crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
		}

		if (crc != lastCrc && crc != lastCrc2)
		{
			unsigned long timeCrc = 0L;

			for (i = 0; i < 4; i++)
			{
				timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
			}

			for (i = 0; i < 4; i++)
			{
				timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
			}

			EnterCriticalSection (&critRandProt);
			RandaddLong (timeCrc);
			RandaddLong (crc);
			LeaveCriticalSection (&critRandProt);
		}
		lastCrc2 = lastCrc;
		lastCrc = crc;

	}
	return 0;
}

/* Capture the keyboard, as long as the event is not the same as the last two
   events :- add a crc of the event to the pool along with a crc of the time
   difference between this event and the last */
LRESULT CALLBACK
KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
{
	static int lLastKey, lLastKey2;
	static DWORD dwLastTimer;
	int nKey = (lParam & 0x00ff0000) >> 16;
	int nCapture = 0;

	if (nCode < 0)
		return CallNextHookEx (hMouse, nCode, wParam, lParam);

	if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
	    (lParam & 0x80000000))
	{
		if (nKey != lLastKey)
			nCapture = 1;	/* Capture this key */
		else if (nKey != lLastKey2)
			nCapture = 1;	/* Allow for one repeat */
	}
	if (nCapture)
	{
		DWORD dwTimer = GetTickCount ();
		DWORD j = dwLastTimer - dwTimer;
		unsigned long timeCrc = 0L;
		int i;

		dwLastTimer = dwTimer;
		lLastKey2 = lLastKey;
		lLastKey = nKey;

		for (i = 0; i < 4; i++)
		{
			timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
		}

		for (i = 0; i < 4; i++)
		{
			timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
		}

		EnterCriticalSection (&critRandProt);
		RandaddLong (lParam);
		RandaddLong (timeCrc);
		LeaveCriticalSection (&critRandProt);
	}
	return 0;
}

/* This is the thread function which will poll the system for randomness */
void
ThreadSafeThreadFunction (void *dummy)
{
	if (dummy);		/* Remove unused parameter warning */

	for (;;)
	{
		EnterCriticalSection (&critRandProt);

		if (bThreadTerminate == TRUE)
		{
			bThreadTerminate = FALSE;
			LeaveCriticalSection (&critRandProt);
			_endthread ();
		}
		else
		{
			FastPoll ();
		}

		LeaveCriticalSection (&critRandProt);

		Sleep (250);
	}
}

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

typedef
  DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
				     DWORD dwLevel, DWORD dwOptions,
				     LPBYTE * lpBuffer);
typedef
  DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
typedef
  DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);

NETSTATISTICSGET pNetStatisticsGet = NULL;
NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
NETAPIBUFFERFREE pNetApiBufferFree = NULL;

/* This is the slowpoll function which gathers up network/hard drive
   performance data for the random pool */
void
SlowPollWinNT (void)
{

⌨️ 快捷键说明

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