rand_win.c
来自「一个用于点对点传输加密的工具包源码」· C语言 代码 · 共 733 行 · 第 1/2 页
C
733 行
* on NT4 even though it exists in SP3 (or SP6) and * higher. */ if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && osverinfo.dwMajorVersion < 5) cursor = 0; } if (cursor) { /* cursor position */ /* assume 2 bytes of entropy */ CURSORINFO ci; ci.cbSize = sizeof(CURSORINFO); if (cursor(&ci)) RAND_add(&ci, ci.cbSize, 2); } if (queue) { /* message queue status */ /* assume 1 byte of entropy */ w = queue(QS_ALLEVENTS); RAND_add(&w, sizeof(w), 1); } FreeLibrary(user); } /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm * (Win 9x and 2000 only, not available on NT) * * This seeding method was proposed in Peter Gutmann, Software * Generation of Practically Strong Random Numbers, * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html * revised version at http://www.cryptoengines.com/~peter/06_random.pdf * (The assignment of entropy estimates below is arbitrary, but based * on Peter's analysis the full poll appears to be safe. Additional * interactive seeding is encouraged.) */ if (kernel) { CREATETOOLHELP32SNAPSHOT snap; HANDLE handle; HEAP32FIRST heap_first; HEAP32NEXT heap_next; HEAP32LIST heaplist_first, heaplist_next; PROCESS32 process_first, process_next; THREAD32 thread_first, thread_next; MODULE32 module_first, module_next; HEAPLIST32 hlist; HEAPENTRY32 hentry; PROCESSENTRY32 p; THREADENTRY32 t; MODULEENTRY32 m; snap = (CREATETOOLHELP32SNAPSHOT) GetProcAddress(kernel, "CreateToolhelp32Snapshot"); heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); process_first = (PROCESS32) GetProcAddress(kernel, "Process32First"); process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next"); thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); if (snap && heap_first && heap_next && heaplist_first && heaplist_next && process_first && process_next && thread_first && thread_next && module_first && module_next && (handle = snap(TH32CS_SNAPALL,0)) != NULL) { /* heap list and heap walking */ /* HEAPLIST32 contains 3 fields that will change with * each entry. Consider each field a source of 1 byte * of entropy. * HEAPENTRY32 contains 5 fields that will change with * each entry. Consider each field a source of 1 byte * of entropy. */ hlist.dwSize = sizeof(HEAPLIST32); if (heaplist_first(handle, &hlist)) do { RAND_add(&hlist, hlist.dwSize, 3); hentry.dwSize = sizeof(HEAPENTRY32); if (heap_first(&hentry, hlist.th32ProcessID, hlist.th32HeapID)) { int entrycnt = 50; do RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) && --entrycnt > 0); } } while (heaplist_next(handle, &hlist)); /* process walking */ /* PROCESSENTRY32 contains 9 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ p.dwSize = sizeof(PROCESSENTRY32); if (process_first(handle, &p)) do RAND_add(&p, p.dwSize, 9); while (process_next(handle, &p)); /* thread walking */ /* THREADENTRY32 contains 6 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ t.dwSize = sizeof(THREADENTRY32); if (thread_first(handle, &t)) do RAND_add(&t, t.dwSize, 6); while (thread_next(handle, &t)); /* module walking */ /* MODULEENTRY32 contains 9 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ m.dwSize = sizeof(MODULEENTRY32); if (module_first(handle, &m)) do RAND_add(&m, m.dwSize, 9); while (module_next(handle, &m)); CloseHandle(handle); } FreeLibrary(kernel); }#ifdef DEBUG printf("Exiting RAND_poll\n");#endif return(1);}int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) { double add_entropy=0; switch (iMsg) { case WM_KEYDOWN: { static WPARAM key; if (key != wParam) add_entropy = 0.05; key = wParam; } break; case WM_MOUSEMOVE: { static int lastx,lasty,lastdx,lastdy; int x,y,dx,dy; x=LOWORD(lParam); y=HIWORD(lParam); dx=lastx-x; dy=lasty-y; if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0) add_entropy=.2; lastx=x, lasty=y; lastdx=dx, lastdy=dy; } break; } readtimer(); RAND_add(&iMsg, sizeof(iMsg), add_entropy); RAND_add(&wParam, sizeof(wParam), 0); RAND_add(&lParam, sizeof(lParam), 0); return (RAND_status()); }void RAND_screen(void) /* function available for backward compatibility */{ RAND_poll(); readscreen();}/* feed timing information to the PRNG */static void readtimer(void){ DWORD w; LARGE_INTEGER l; static int have_perfc = 1;#ifndef __GNUC__ static int have_tsc = 1; DWORD cyclecount; if (have_tsc) { __try { __asm { rdtsc mov cyclecount, eax } RAND_add(&cyclecount, sizeof(cyclecount), 1); } __except(EXCEPTION_EXECUTE_HANDLER) { have_tsc = 0; } }#else# define have_tsc 0#endif if (have_perfc) { if (QueryPerformanceCounter(&l) == 0) have_perfc = 0; else RAND_add(&l, sizeof(l), 0); } if (!have_tsc && !have_perfc) { w = GetTickCount(); RAND_add(&w, sizeof(w), 0); }}/* feed screen contents to PRNG *//***************************************************************************** * * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. * * Code adapted from * <URL:http://www.microsoft.com/kb/developr/win_dk/q97193.htm>; * the original copyright message is: * * (C) Copyright Microsoft Corp. 1993. All rights reserved. * * You have a royalty-free right to use, modify, reproduce and * distribute the Sample Files (and/or any modified version) in * any way you find useful, provided that you agree that * Microsoft has no warranty obligations or liability for any * Sample Application Files which are modified. */static void readscreen(void){ HDC hScrDC; /* screen DC */ HDC hMemDC; /* memory DC */ HBITMAP hBitmap; /* handle for our bitmap */ HBITMAP hOldBitmap; /* handle for previous bitmap */ BITMAP bm; /* bitmap properties */ unsigned int size; /* size of bitmap */ char *bmbits; /* contents of bitmap */ int w; /* screen width */ int h; /* screen height */ int y; /* y-coordinate of screen lines to grab */ int n = 16; /* number of screen lines to grab at a time */ /* Create a screen DC and a memory DC compatible to screen DC */ hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); hMemDC = CreateCompatibleDC(hScrDC); /* Get screen resolution */ w = GetDeviceCaps(hScrDC, HORZRES); h = GetDeviceCaps(hScrDC, VERTRES); /* Create a bitmap compatible with the screen DC */ hBitmap = CreateCompatibleBitmap(hScrDC, w, n); /* Select new bitmap into memory DC */ hOldBitmap = SelectObject(hMemDC, hBitmap); /* Get bitmap properties */ GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes; bmbits = OPENSSL_malloc(size); if (bmbits) { /* Now go through the whole screen, repeatedly grabbing n lines */ for (y = 0; y < h-n; y += n) { unsigned char md[MD_DIGEST_LENGTH]; /* Bitblt screen DC to memory DC */ BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY); /* Copy bitmap bits from memory DC to bmbits */ GetBitmapBits(hBitmap, size, bmbits); /* Get the hash of the bitmap */ MD(bmbits,size,md); /* Seed the random generator with the hash value */ RAND_add(md, MD_DIGEST_LENGTH, 0); } OPENSSL_free(bmbits); } /* Select old bitmap back into memory DC */ hBitmap = SelectObject(hMemDC, hOldBitmap); /* Clean up */ DeleteObject(hBitmap); DeleteDC(hMemDC); DeleteDC(hScrDC);}#else /* Unix version */#include <time.h>int RAND_poll(void){ unsigned long l; pid_t curr_pid = getpid();#ifdef DEVRANDOM FILE *fh;#endif#ifdef DEVRANDOM /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD * have this. Use /dev/urandom if you can as /dev/random may block * if it runs out of random entries. */ if ((fh = fopen(DEVRANDOM, "r")) != NULL) { unsigned char tmpbuf[ENTROPY_NEEDED]; int n; setvbuf(fh, NULL, _IONBF, 0); n=fread((unsigned char *)tmpbuf,1,ENTROPY_NEEDED,fh); fclose(fh); RAND_add(tmpbuf,sizeof tmpbuf,n); memset(tmpbuf,0,n); }#endif /* put in some default random data, we need more than just this */ l=curr_pid; RAND_add(&l,sizeof(l),0); l=getuid(); RAND_add(&l,sizeof(l),0); l=time(NULL); RAND_add(&l,sizeof(l),0);#ifdef DEVRANDOM return 1;#endif return 0;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?