The WinSock library is now loaded at run-time, which means we can
[u/mdw/putty] / noise.c
CommitLineData
374330e2 1/*
2 * Noise generation for PuTTY's cryptographic random number
3 * generator.
4 */
5
374330e2 6#include <stdio.h>
7
8#include "putty.h"
9#include "ssh.h"
d5859615 10#include "storage.h"
374330e2 11
12/*
a4e14164 13 * GetSystemPowerStatus function.
14 */
32874aea 15typedef BOOL(WINAPI * gsps_t) (LPSYSTEM_POWER_STATUS);
75cab814 16static gsps_t gsps;
a4e14164 17
18/*
374330e2 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
32874aea 24void noise_get_heavy(void (*func) (void *, int))
25{
374330e2 26 HANDLE srch;
374330e2 27 WIN32_FIND_DATA finddata;
32874aea 28 char winpath[MAX_PATH + 3];
a4e14164 29 HMODULE mod;
374330e2 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
d5859615 41 read_random_seed(func);
e3ac3c05 42 /* Update the seed immediately, in case another instance uses it. */
43 random_save_seed();
a4e14164 44
45 gsps = NULL;
46 mod = GetModuleHandle("KERNEL32");
47 if (mod) {
32874aea 48 gsps = (gsps_t) GetProcAddress(mod, "GetSystemPowerStatus");
a4e14164 49 }
374330e2 50}
51
32874aea 52void random_save_seed(void)
53{
d5859615 54 int len;
55 void *data;
374330e2 56
93b581bd 57 if (random_active) {
58 random_get_savedata(&data, &len);
59 write_random_seed(data, len);
e3ac3c05 60 sfree(data);
93b581bd 61 }
de3df031 62}
63
64/*
374330e2 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 */
32874aea 69void noise_get_light(void (*func) (void *, int))
70{
374330e2 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
a4e14164 82 /*
83 * Call GetSystemPowerStatus if present.
84 */
85 if (gsps) {
32874aea 86 if (gsps(&pwrstat))
87 func(&pwrstat, sizeof(pwrstat));
a4e14164 88 }
374330e2 89}
90
91/*
7d6ee6ff 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 */
32874aea 97void noise_regular(void)
98{
7d6ee6ff 99 HWND w;
100 DWORD z;
101 POINT pt;
102 MEMORYSTATUS memstat;
103 FILETIME times[4];
104
32874aea 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));
7d6ee6ff 113
32874aea 114 GetCursorPos(&pt);
115 random_add_noise(&pt, sizeof(pt));
7d6ee6ff 116
32874aea 117 GlobalMemoryStatus(&memstat);
118 random_add_noise(&memstat, sizeof(memstat));
7d6ee6ff 119
32874aea 120 GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
121 times + 3);
7d6ee6ff 122 random_add_noise(&times, sizeof(times));
32874aea 123 GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
124 times + 3);
7d6ee6ff 125 random_add_noise(&times, sizeof(times));
126}
127
128/*
374330e2 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 */
f7f27309 134void noise_ultralight(unsigned long data)
32874aea 135{
374330e2 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}