The WinSock library is now loaded at run-time, which means we can
[u/mdw/putty] / noise.c
1 /*
2 * Noise generation for PuTTY's cryptographic random number
3 * generator.
4 */
5
6 #include <stdio.h>
7
8 #include "putty.h"
9 #include "ssh.h"
10 #include "storage.h"
11
12 /*
13 * GetSystemPowerStatus function.
14 */
15 typedef BOOL(WINAPI * gsps_t) (LPSYSTEM_POWER_STATUS);
16 static gsps_t gsps;
17
18 /*
19 * This function is called once, at PuTTY startup, and will do some
20 * seriously silly things like listing directories and getting disk
21 * free space and a process snapshot.
22 */
23
24 void noise_get_heavy(void (*func) (void *, int))
25 {
26 HANDLE srch;
27 WIN32_FIND_DATA finddata;
28 char winpath[MAX_PATH + 3];
29 HMODULE mod;
30
31 GetWindowsDirectory(winpath, sizeof(winpath));
32 strcat(winpath, "\\*");
33 srch = FindFirstFile(winpath, &finddata);
34 if (srch != INVALID_HANDLE_VALUE) {
35 do {
36 func(&finddata, sizeof(finddata));
37 } while (FindNextFile(srch, &finddata));
38 FindClose(srch);
39 }
40
41 read_random_seed(func);
42 /* Update the seed immediately, in case another instance uses it. */
43 random_save_seed();
44
45 gsps = NULL;
46 mod = GetModuleHandle("KERNEL32");
47 if (mod) {
48 gsps = (gsps_t) GetProcAddress(mod, "GetSystemPowerStatus");
49 }
50 }
51
52 void random_save_seed(void)
53 {
54 int len;
55 void *data;
56
57 if (random_active) {
58 random_get_savedata(&data, &len);
59 write_random_seed(data, len);
60 sfree(data);
61 }
62 }
63
64 /*
65 * This function is called every time the random pool needs
66 * stirring, and will acquire the system time in all available
67 * forms and the battery status.
68 */
69 void noise_get_light(void (*func) (void *, int))
70 {
71 SYSTEMTIME systime;
72 DWORD adjust[2];
73 BOOL rubbish;
74 SYSTEM_POWER_STATUS pwrstat;
75
76 GetSystemTime(&systime);
77 func(&systime, sizeof(systime));
78
79 GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);
80 func(&adjust, sizeof(adjust));
81
82 /*
83 * Call GetSystemPowerStatus if present.
84 */
85 if (gsps) {
86 if (gsps(&pwrstat))
87 func(&pwrstat, sizeof(pwrstat));
88 }
89 }
90
91 /*
92 * This function is called on a timer, and it will monitor
93 * frequently changing quantities such as the state of physical and
94 * virtual memory, the state of the process's message queue, which
95 * window is in the foreground, which owns the clipboard, etc.
96 */
97 void noise_regular(void)
98 {
99 HWND w;
100 DWORD z;
101 POINT pt;
102 MEMORYSTATUS memstat;
103 FILETIME times[4];
104
105 w = GetForegroundWindow();
106 random_add_noise(&w, sizeof(w));
107 w = GetCapture();
108 random_add_noise(&w, sizeof(w));
109 w = GetClipboardOwner();
110 random_add_noise(&w, sizeof(w));
111 z = GetQueueStatus(QS_ALLEVENTS);
112 random_add_noise(&z, sizeof(z));
113
114 GetCursorPos(&pt);
115 random_add_noise(&pt, sizeof(pt));
116
117 GlobalMemoryStatus(&memstat);
118 random_add_noise(&memstat, sizeof(memstat));
119
120 GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
121 times + 3);
122 random_add_noise(&times, sizeof(times));
123 GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
124 times + 3);
125 random_add_noise(&times, sizeof(times));
126 }
127
128 /*
129 * This function is called on every keypress or mouse move, and
130 * will add the current Windows time and performance monitor
131 * counter to the noise pool. It gets the scan code or mouse
132 * position passed in.
133 */
134 void noise_ultralight(unsigned long data)
135 {
136 DWORD wintime;
137 LARGE_INTEGER perftime;
138
139 random_add_noise(&data, sizeof(DWORD));
140
141 wintime = GetTickCount();
142 random_add_noise(&wintime, sizeof(DWORD));
143
144 if (QueryPerformanceCounter(&perftime))
145 random_add_noise(&perftime, sizeof(perftime));
146 }