Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'unix/noise.c')
-rw-r--r--unix/noise.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/unix/noise.c b/unix/noise.c
new file mode 100644
index 00000000..0fbf8c4d
--- /dev/null
+++ b/unix/noise.c
@@ -0,0 +1,130 @@
+/*
+ * Noise generation for PuTTY's cryptographic random number
+ * generator.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "putty.h"
+#include "ssh.h"
+#include "storage.h"
+
+static bool read_dev_urandom(char *buf, int len)
+{
+ int fd;
+ int ngot, ret;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ ngot = 0;
+ while (ngot < len) {
+ ret = read(fd, buf+ngot, len-ngot);
+ if (ret < 0) {
+ close(fd);
+ return false;
+ }
+ ngot += ret;
+ }
+
+ close(fd);
+
+ return true;
+}
+
+/*
+ * This function is called once, at PuTTY startup. It will do some
+ * slightly silly things such as fetching an entire process listing
+ * and scanning /tmp, load the saved random seed from disk, and
+ * also read 32 bytes out of /dev/urandom.
+ */
+
+void noise_get_heavy(void (*func) (void *, int))
+{
+ char buf[512];
+ FILE *fp;
+ int ret;
+ bool got_dev_urandom = false;
+
+ if (read_dev_urandom(buf, 32)) {
+ got_dev_urandom = true;
+ func(buf, 32);
+ }
+
+ fp = popen("ps -axu 2>/dev/null", "r");
+ if (fp) {
+ while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
+ func(buf, ret);
+ pclose(fp);
+ } else if (!got_dev_urandom) {
+ fprintf(stderr, "popen: %s\n"
+ "Unable to access fallback entropy source\n", strerror(errno));
+ exit(1);
+ }
+
+ fp = popen("ls -al /tmp 2>/dev/null", "r");
+ if (fp) {
+ while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
+ func(buf, ret);
+ pclose(fp);
+ } else if (!got_dev_urandom) {
+ fprintf(stderr, "popen: %s\n"
+ "Unable to access fallback entropy source\n", strerror(errno));
+ exit(1);
+ }
+
+ read_random_seed(func);
+}
+
+/*
+ * This function is called on a timer, and grabs as much changeable
+ * system data as it can quickly get its hands on.
+ */
+void noise_regular(void)
+{
+ int fd;
+ int ret;
+ char buf[512];
+ struct rusage rusage;
+
+ if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) {
+ while ( (ret = read(fd, buf, sizeof(buf))) > 0)
+ random_add_noise(NOISE_SOURCE_MEMINFO, buf, ret);
+ close(fd);
+ }
+ if ((fd = open("/proc/stat", O_RDONLY)) >= 0) {
+ while ( (ret = read(fd, buf, sizeof(buf))) > 0)
+ random_add_noise(NOISE_SOURCE_STAT, buf, ret);
+ close(fd);
+ }
+ getrusage(RUSAGE_SELF, &rusage);
+ random_add_noise(NOISE_SOURCE_RUSAGE, &rusage, sizeof(rusage));
+}
+
+/*
+ * This function is called on every keypress or mouse move, and
+ * will add the current time to the noise pool. It gets the scan
+ * code or mouse position passed in, and adds that too.
+ */
+void noise_ultralight(NoiseSourceId id, unsigned long data)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ random_add_noise(NOISE_SOURCE_TIME, &tv, sizeof(tv));
+ random_add_noise(id, &data, sizeof(data));
+}
+
+uint64_t prng_reseed_time_ms(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}