]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - unix/uxnoise.c
Move MODULE files out of individual project directories into a
[PuTTY.git] / unix / uxnoise.c
1 /*
2  * Noise generation for PuTTY's cryptographic random number
3  * generator.
4  */
5
6 #include <stdio.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <sys/time.h>
10 #include <sys/resource.h>
11
12 #include "putty.h"
13 #include "ssh.h"
14 #include "storage.h"
15
16 static int read_dev_urandom(char *buf, int len)
17 {
18     int fd;
19     int ngot, ret;
20
21     fd = open("/dev/urandom", O_RDONLY);
22     if (fd < 0)
23         return 0;
24
25     ngot = 0;
26     while (ngot < len) {
27         ret = read(fd, buf+ngot, len-ngot);
28         if (ret < 0) {
29             close(fd);
30             return 0;
31         }
32         ngot += ret;
33     }
34
35     return 1;
36 }
37
38 /*
39  * This function is called once, at PuTTY startup. It will do some
40  * slightly silly things such as fetching an entire process listing
41  * and scanning /tmp, load the saved random seed from disk, and
42  * also read 32 bytes out of /dev/urandom.
43  */
44
45 void noise_get_heavy(void (*func) (void *, int))
46 {
47     char buf[512];
48     FILE *fp;
49     int ret;
50
51     if (read_dev_urandom(buf, 32))
52         func(buf, 32);
53
54     fp = popen("ps -axu 2>/dev/null", "r");
55     while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
56         func(buf, ret);
57     pclose(fp);
58
59     fp = popen("ls -al /tmp 2>/dev/null", "r");
60     while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
61         func(buf, ret);
62     pclose(fp);
63
64     read_random_seed(func);
65     random_save_seed();
66 }
67
68 void random_save_seed(void)
69 {
70     int len;
71     void *data;
72
73     if (random_active) {
74         random_get_savedata(&data, &len);
75         write_random_seed(data, len);
76         sfree(data);
77     }
78 }
79
80 /*
81  * This function is called every time the random pool needs
82  * stirring, and will acquire the system time.
83  */
84 void noise_get_light(void (*func) (void *, int))
85 {
86     struct timeval tv;
87     gettimeofday(&tv, NULL);
88     func(&tv, sizeof(tv));
89 }
90
91 /*
92  * This function is called on a timer, and grabs as much changeable
93  * system data as it can quickly get its hands on.
94  */
95 void noise_regular(void)
96 {
97     int fd;
98     int ret;
99     char buf[512];
100     struct rusage rusage;
101
102     if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) {
103         while ( (ret = read(fd, buf, sizeof(buf))) > 0)
104             random_add_noise(buf, ret);
105         close(fd);
106     }
107     if ((fd = open("/proc/stat", O_RDONLY)) >= 0) {
108         while ( (ret = read(fd, buf, sizeof(buf))) > 0)
109             random_add_noise(buf, ret);
110         close(fd);
111     }
112     getrusage(RUSAGE_SELF, &rusage);
113     random_add_noise(&rusage, sizeof(rusage));
114 }
115
116 /*
117  * This function is called on every keypress or mouse move, and
118  * will add the current time to the noise pool. It gets the scan
119  * code or mouse position passed in, and adds that too.
120  */
121 void noise_ultralight(unsigned long data)
122 {
123     struct timeval tv;
124     gettimeofday(&tv, NULL);
125     random_add_noise(&tv, sizeof(tv));
126     random_add_noise(&data, sizeof(data));
127 }