]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - noise.c
Silly mistake - restore-cursor-pos doesn't make sure the cursor
[PuTTY.git] / noise.c
1 /*
2  * Noise generation for PuTTY's cryptographic random number
3  * generator.
4  */
5
6 #include <windows.h>
7 #include <stdio.h>
8
9 #include "putty.h"
10 #include "ssh.h"
11
12 static char seedpath[2*MAX_PATH+10] = "\0";
13
14 /*
15  * Find the random seed file path and store it in `seedpath'.
16  */
17 static void get_seedpath(void) {
18     HKEY rkey;
19     DWORD type, size;
20
21     size = sizeof(seedpath);
22
23     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey)==ERROR_SUCCESS) {
24         int ret = RegQueryValueEx(rkey, "RandSeedFile",
25                                   0, &type, seedpath, &size);
26         if (ret != ERROR_SUCCESS || type != REG_SZ)
27             seedpath[0] = '\0';
28         RegCloseKey(rkey);
29     } else
30         seedpath[0] = '\0';
31
32     if (!seedpath[0]) {
33         int len, ret;
34
35         len = GetEnvironmentVariable("HOMEDRIVE", seedpath, sizeof(seedpath));
36         ret = GetEnvironmentVariable("HOMEPATH", seedpath+len,
37                                       sizeof(seedpath)-len);
38         if (ret == 0) {                /* probably win95; store in \WINDOWS */
39             GetWindowsDirectory(seedpath, sizeof(seedpath));
40             len = strlen(seedpath);
41         } else
42             len += ret;
43         strcpy(seedpath+len, "\\PUTTY.RND");
44     }
45 }
46
47 /*
48  * This function is called once, at PuTTY startup, and will do some
49  * seriously silly things like listing directories and getting disk
50  * free space and a process snapshot.
51  */
52
53 void noise_get_heavy(void (*func) (void *, int)) {
54     HANDLE srch;
55     HANDLE seedf;
56     WIN32_FIND_DATA finddata;
57     char winpath[MAX_PATH+3];
58
59     GetWindowsDirectory(winpath, sizeof(winpath));
60     strcat(winpath, "\\*");
61     srch = FindFirstFile(winpath, &finddata);
62     if (srch != INVALID_HANDLE_VALUE) {
63         do {
64             func(&finddata, sizeof(finddata));
65         } while (FindNextFile(srch, &finddata));
66         FindClose(srch);
67     }
68
69     if (!seedpath[0])
70         get_seedpath();
71
72     seedf = CreateFile(seedpath, GENERIC_READ,
73                        FILE_SHARE_READ | FILE_SHARE_WRITE,
74                        NULL, OPEN_EXISTING, 0, NULL);
75
76     if (seedf != INVALID_HANDLE_VALUE) {
77         while (1) {
78             char buf[1024];
79             DWORD len;
80
81             if (ReadFile(seedf, buf, sizeof(buf), &len, NULL) && len)
82                 func(buf, len);
83             else
84                 break;
85         }
86         CloseHandle(seedf);
87     }
88 }
89
90 void random_save_seed(void) {
91     HANDLE seedf;
92
93     if (!seedpath[0])
94         get_seedpath();
95
96     seedf = CreateFile(seedpath, GENERIC_WRITE, 0,
97                        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
98
99     if (seedf != INVALID_HANDLE_VALUE) {
100         int len;
101         DWORD lenwritten;
102         void *data;
103
104         random_get_savedata(&data, &len);
105         WriteFile(seedf, data, len, &lenwritten, NULL);
106         CloseHandle(seedf);
107     }
108 }
109
110 /*
111  * This function is called every time the random pool needs
112  * stirring, and will acquire the system time in all available
113  * forms and the battery status.
114  */
115 void noise_get_light(void (*func) (void *, int)) {
116     SYSTEMTIME systime;
117     DWORD adjust[2];
118     BOOL rubbish;
119     SYSTEM_POWER_STATUS pwrstat;
120
121     GetSystemTime(&systime);
122     func(&systime, sizeof(systime));
123
124     GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);
125     func(&adjust, sizeof(adjust));
126
127 #ifndef WIN32S_COMPAT
128     if (GetSystemPowerStatus(&pwrstat))
129         func(&pwrstat, sizeof(pwrstat));
130 #endif
131 }
132
133 /*
134  * This function is called on every keypress or mouse move, and
135  * will add the current Windows time and performance monitor
136  * counter to the noise pool. It gets the scan code or mouse
137  * position passed in.
138  */
139 void noise_ultralight(DWORD data) {
140     DWORD wintime;
141     LARGE_INTEGER perftime;
142
143     random_add_noise(&data, sizeof(DWORD));
144
145     wintime = GetTickCount();
146     random_add_noise(&wintime, sizeof(DWORD));
147
148     if (QueryPerformanceCounter(&perftime))
149         random_add_noise(&perftime, sizeof(perftime));
150 }