]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winnoise.c
GTK2: Return 2.20 compatibility back
[PuTTY.git] / windows / winnoise.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 #include <wincrypt.h>
13
14 DECL_WINDOWS_FUNCTION(static, BOOL, CryptAcquireContextA,
15                       (HCRYPTPROV *, LPCTSTR, LPCTSTR, DWORD, DWORD));
16 DECL_WINDOWS_FUNCTION(static, BOOL, CryptGenRandom,
17                       (HCRYPTPROV, DWORD, BYTE *));
18 DECL_WINDOWS_FUNCTION(static, BOOL, CryptReleaseContext,
19                       (HCRYPTPROV, DWORD));
20 static HMODULE wincrypt_module = NULL;
21
22 /*
23  * This function is called once, at PuTTY startup.
24  */
25
26 void noise_get_heavy(void (*func) (void *, int))
27 {
28     HANDLE srch;
29     WIN32_FIND_DATA finddata;
30     DWORD pid;
31     HCRYPTPROV crypt_provider;
32     char winpath[MAX_PATH + 3];
33
34     GetWindowsDirectory(winpath, sizeof(winpath));
35     strcat(winpath, "\\*");
36     srch = FindFirstFile(winpath, &finddata);
37     if (srch != INVALID_HANDLE_VALUE) {
38         do {
39             func(&finddata, sizeof(finddata));
40         } while (FindNextFile(srch, &finddata));
41         FindClose(srch);
42     }
43
44     pid = GetCurrentProcessId();
45     func(&pid, sizeof(pid));
46
47     if (!wincrypt_module) {
48         wincrypt_module = load_system32_dll("advapi32.dll");
49         GET_WINDOWS_FUNCTION(wincrypt_module, CryptAcquireContextA);
50         GET_WINDOWS_FUNCTION(wincrypt_module, CryptGenRandom);
51         GET_WINDOWS_FUNCTION(wincrypt_module, CryptReleaseContext);
52     }
53
54     if (wincrypt_module && p_CryptAcquireContextA &&
55         p_CryptGenRandom && p_CryptReleaseContext &&
56         p_CryptAcquireContextA(&crypt_provider, NULL, NULL, PROV_RSA_FULL,
57                                CRYPT_VERIFYCONTEXT)) {
58         BYTE buf[32];
59         if (p_CryptGenRandom(crypt_provider, 32, buf)) {
60             func(buf, sizeof(buf));
61         }
62         p_CryptReleaseContext(crypt_provider, 0);
63     }
64
65     read_random_seed(func);
66     /* Update the seed immediately, in case another instance uses it. */
67     random_save_seed();
68 }
69
70 void random_save_seed(void)
71 {
72     int len;
73     void *data;
74
75     if (random_active) {
76         random_get_savedata(&data, &len);
77         write_random_seed(data, len);
78         sfree(data);
79     }
80 }
81
82 /*
83  * This function is called every time the random pool needs
84  * stirring, and will acquire the system time in all available
85  * forms.
86  */
87 void noise_get_light(void (*func) (void *, int))
88 {
89     SYSTEMTIME systime;
90     DWORD adjust[2];
91     BOOL rubbish;
92
93     GetSystemTime(&systime);
94     func(&systime, sizeof(systime));
95
96     GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);
97     func(&adjust, sizeof(adjust));
98 }
99
100 /*
101  * This function is called on a timer, and it will monitor
102  * frequently changing quantities such as the state of physical and
103  * virtual memory, the state of the process's message queue, which
104  * window is in the foreground, which owns the clipboard, etc.
105  */
106 void noise_regular(void)
107 {
108     HWND w;
109     DWORD z;
110     POINT pt;
111     MEMORYSTATUS memstat;
112     FILETIME times[4];
113
114     w = GetForegroundWindow();
115     random_add_noise(&w, sizeof(w));
116     w = GetCapture();
117     random_add_noise(&w, sizeof(w));
118     w = GetClipboardOwner();
119     random_add_noise(&w, sizeof(w));
120     z = GetQueueStatus(QS_ALLEVENTS);
121     random_add_noise(&z, sizeof(z));
122
123     GetCursorPos(&pt);
124     random_add_noise(&pt, sizeof(pt));
125
126     GlobalMemoryStatus(&memstat);
127     random_add_noise(&memstat, sizeof(memstat));
128
129     GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
130                    times + 3);
131     random_add_noise(&times, sizeof(times));
132     GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
133                     times + 3);
134     random_add_noise(&times, sizeof(times));
135 }
136
137 /*
138  * This function is called on every keypress or mouse move, and
139  * will add the current Windows time and performance monitor
140  * counter to the noise pool. It gets the scan code or mouse
141  * position passed in.
142  */
143 void noise_ultralight(unsigned long data)
144 {
145     DWORD wintime;
146     LARGE_INTEGER perftime;
147
148     random_add_noise(&data, sizeof(DWORD));
149
150     wintime = GetTickCount();
151     random_add_noise(&wintime, sizeof(DWORD));
152
153     if (QueryPerformanceCounter(&perftime))
154         random_add_noise(&perftime, sizeof(perftime));
155 }