yseed.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* -*- Mode: C; c-file-style: "bsd" -*- */
  2. /*
  3.  * Yarrow - Cryptographic Pseudo-Random Number Generator
  4.  * Copyright (c) 2000 Zero-Knowledge Systems, Inc.
  5.  *
  6.  * See the accompanying LICENSE file for license information.
  7.  */
  8. #ifdef WIN32
  9. # ifndef _WIN32_WINNT
  10. #  define _WIN32_WINNT 0x0400 /* for wincrypt.h */
  11. # endif
  12. # include <windows.h>
  13. # include <wincrypt.h>
  14. # include <tlhelp32.h>
  15. #endif
  16. #include "yarrow.h"
  17. #include "yexcep.h"
  18. #ifdef WIN32
  19. /* Intel hardware RNG CSP -- available from
  20.  * http://developer.intel.com/design/security/rng/redist_license.htm
  21.  */
  22. # define PROV_INTEL_SEC 22
  23. # define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
  24. typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *, LPCTSTR, LPCTSTR,
  25.    DWORD, DWORD);
  26. typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
  27. typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD);
  28. typedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID);
  29. typedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO);
  30. typedef DWORD (WINAPI *GETQUEUESTATUS)(UINT);
  31. typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
  32. typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, DWORD);
  33. typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
  34. typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
  35. typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
  36. typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
  37. typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
  38. #define RAND_add(sample, size, entropy_bytes) 
  39.   Yarrow_Input(y, (source_id), (sample), (size), 8*(entropy_bytes))
  40. #include "yarrow.h"
  41. static void readtimer(Yarrow_CTX *, unsigned);
  42. int Yarrow_Poll(Yarrow_CTX *y, unsigned source_id)
  43. {
  44.     EXCEP_DECL;
  45.     MEMORYSTATUS m;
  46.     HCRYPTPROV hProvider = 0;
  47.     BYTE buf[64];
  48.     DWORD w;
  49.     HWND h;
  50.     HMODULE advapi, kernel, user;
  51.     CRYPTACQUIRECONTEXT acquire;
  52.     CRYPTGENRANDOM gen;
  53.     CRYPTRELEASECONTEXT release;
  54.     /* load functions dynamically - not available on all systems */
  55.     advapi = GetModuleHandle("ADVAPI32.DLL");
  56.     kernel = GetModuleHandle("KERNEL32.DLL");
  57.     user = GetModuleHandle("USER32.DLL");
  58.   
  59.     if (advapi)
  60.     {
  61. acquire = (CRYPTACQUIRECONTEXT) GetProcAddress(advapi,
  62.        "CryptAcquireContextA");
  63. gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
  64.       "CryptGenRandom");
  65. release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
  66.        "CryptReleaseContext");
  67.     }
  68.   
  69.     if (acquire && gen && release)
  70.     {
  71. /* poll the CryptoAPI PRNG */
  72. if (acquire(&hProvider, 0, 0, PROV_RSA_FULL,
  73.     CRYPT_VERIFYCONTEXT))
  74. {
  75.     if (gen(hProvider, sizeof(buf), buf) != 0)
  76.     {
  77. RAND_add(buf, sizeof(buf), 0);
  78. # ifdef DEBUG
  79. printf("randomness from PROV_RSA_FULLn");
  80. # endif
  81.     }
  82.     release(hProvider, 0); 
  83. }
  84.       
  85. /* poll the Pentium PRG with CryptoAPI */
  86. if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
  87. {
  88.     if (gen(hProvider, sizeof(buf), buf) != 0)
  89.     {
  90. RAND_add(buf, sizeof(buf), 0);
  91. # ifdef DEBUG
  92. printf("randomness from PROV_INTEL_SECn");
  93. # endif
  94.     }
  95.     release(hProvider, 0);
  96. }
  97.     }
  98.   
  99.     /* timer data */
  100.     readtimer(y, source_id);
  101.   
  102.     /* memory usage statistics */
  103.     GlobalMemoryStatus(&m);
  104.     RAND_add(&m, sizeof(m), 1);
  105.   
  106.     /* process ID */
  107.     w = GetCurrentProcessId();
  108.     RAND_add(&w, sizeof(w), 0);
  109.   
  110.     if (user)
  111.     {
  112. GETCURSORINFO cursor;
  113. GETFOREGROUNDWINDOW win;
  114. GETQUEUESTATUS queue;
  115.     
  116. win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
  117. cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
  118. queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
  119.     
  120. if (win)
  121. {
  122.     /* window handle */
  123.     h = win();
  124.     RAND_add(&h, sizeof(h), 0);
  125. }
  126.       
  127. if (cursor)
  128. {
  129.     /* cursor position */
  130.     cursor(buf);
  131.     RAND_add(buf, sizeof(buf), 0);
  132. }
  133.       
  134. if (queue)
  135. {
  136.     /* message queue status */
  137.     w = queue(QS_ALLEVENTS);
  138.     RAND_add(&w, sizeof(w), 0);
  139. }
  140.     }
  141.   
  142.     /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
  143.      * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
  144.      * (Win 9x only, not available on NT)
  145.      *
  146.      * This seeding method was proposed in Peter Gutmann, Software
  147.      * Generation of Practically Strong Random Numbers,
  148.      * http://www.cs.auckland.ac.nz/~pgut001/pubs/random2.pdf
  149.      * (The assignment of entropy estimates below is arbitrary, but based
  150.      * on Peter's analysis the full poll appears to be safe. Additional
  151.      * interactive seeding is encouraged.)
  152.      */
  153.     if (kernel)
  154.     {
  155. CREATETOOLHELP32SNAPSHOT snap;
  156. HANDLE handle;
  157.     
  158. HEAP32FIRST heap_first;
  159. HEAP32NEXT heap_next;
  160. HEAP32LIST heaplist_first, heaplist_next;
  161. PROCESS32 process_first, process_next;
  162. THREAD32 thread_first, thread_next;
  163. MODULE32 module_first, module_next;
  164. HEAPLIST32 hlist;
  165. HEAPENTRY32 hentry;
  166. PROCESSENTRY32 p;
  167. THREADENTRY32 t;
  168. MODULEENTRY32 m;
  169.     
  170. snap = (CREATETOOLHELP32SNAPSHOT)
  171.     GetProcAddress(kernel, "CreateToolhelp32Snapshot");
  172. heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
  173. heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
  174. heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
  175. heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
  176. process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
  177. process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
  178. thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
  179. thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
  180. module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
  181. module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");
  182. if (snap && heap_first && heap_next && heaplist_first &&
  183.     heaplist_next && process_first && process_next &&
  184.     thread_first && thread_next && module_first &&
  185.     module_next && (handle = snap(TH32CS_SNAPALL,0)) != NULL)
  186. {
  187.     /* heap list and heap walking */
  188.     hlist.dwSize = sizeof(HEAPLIST32);
  189.     if (heaplist_first(handle, &hlist))
  190. do
  191. {
  192.     RAND_add(&hlist, hlist.dwSize, 0);
  193.     hentry.dwSize = sizeof(HEAPENTRY32);
  194.     if (heap_first(&hentry,
  195.    hlist.th32ProcessID,
  196.    hlist.th32HeapID))
  197. do
  198.     RAND_add(&hentry,
  199.      hentry.dwSize, 0);
  200. while (heap_next(&hentry));
  201. } while (heaplist_next(handle,
  202.        &hlist));
  203.       
  204.     /* process walking */
  205.     p.dwSize = sizeof(PROCESSENTRY32);
  206.     if (process_first(handle, &p))
  207. do
  208.     RAND_add(&p, p.dwSize, 0);
  209. while (process_next(handle, &p));
  210.       
  211.     /* thread walking */
  212.     t.dwSize = sizeof(THREADENTRY32);
  213.     if (thread_first(handle, &t))
  214. do
  215.     RAND_add(&t, t.dwSize, 0);
  216. while (thread_next(handle, &t));
  217.       
  218.     /* module walking */
  219.     m.dwSize = sizeof(MODULEENTRY32);
  220.     if (module_first(handle, &m))
  221. do
  222.     RAND_add(&m, m.dwSize, 1);
  223. while (module_next(handle, &m));
  224.       
  225.     CloseHandle(handle);
  226. }
  227.     }
  228.     TRY( Yarrow_Status( y, NULL, NULL, NULL, NULL ) );
  229.  CATCH:
  230.     EXCEP_RET;
  231. }
  232. /* feed timing information to the PRNG */
  233. static void readtimer(Yarrow_CTX *y, unsigned source_id)
  234. {
  235.     DWORD w, cyclecount;
  236.     LARGE_INTEGER l;
  237.     static int have_perfc = 1;
  238. #ifndef __GNUC__
  239.     static int have_tsc = 1;
  240.     if (have_tsc) {
  241. __try {
  242.     __asm {
  243. rdtsc
  244.     mov cyclecount, eax
  245.     }
  246.     RAND_add(&cyclecount, sizeof(cyclecount), 1);
  247. } __except(EXCEPTION_EXECUTE_HANDLER) {
  248.     have_tsc = 0;
  249. }
  250.     }
  251. #else
  252. # define have_tsc 0
  253. #endif
  254.     if (have_perfc) {
  255. if (QueryPerformanceCounter(&l) == 0)
  256. {
  257.     have_perfc = 0;
  258. }
  259. else
  260. {
  261.     RAND_add(&l, sizeof(l), 0);
  262. }
  263.     }
  264.     if (!have_tsc && !have_perfc) {
  265. w = GetTickCount();
  266. RAND_add(&w, sizeof(w), 0);
  267.     }
  268. }
  269. #else
  270. int Yarrow_Poll(Yarrow_CTX *y, unsigned source_id)
  271. {
  272.     source_id = source_id;
  273.     return Yarrow_Status( y, NULL, NULL, NULL, NULL );
  274. }
  275. #endif