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