]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
random: Read /dev/random in the background with eloop read socket
authorJouni Malinen <j@w1.fi>
Tue, 22 Mar 2011 21:15:00 +0000 (23:15 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 22 Mar 2011 21:15:00 +0000 (23:15 +0200)
This makes it more likely to be able to fetch the 20 octet seed from
/dev/random in cases where other programs may also be competing for
this.

hostapd/main.c
src/crypto/random.c
src/crypto/random.h
wpa_supplicant/wpa_supplicant.c

index 94cdbbad75f8022b15822b6f0e100f745c312245..21b3cca14fe0ace6c83c23760b6b02adf280d186 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "utils/common.h"
 #include "utils/eloop.h"
+#include "crypto/random.h"
 #include "crypto/tls.h"
 #include "common/version.h"
 #include "drivers/driver.h"
@@ -377,6 +378,8 @@ static int hostapd_global_init(struct hapd_interfaces *interfaces)
                return -1;
        }
 
+       random_init();
+
 #ifndef CONFIG_NATIVE_WINDOWS
        eloop_register_signal(SIGHUP, handle_reload, interfaces);
        eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
@@ -397,6 +400,8 @@ static void hostapd_global_deinit(const char *pid_file)
        tncs_global_deinit();
 #endif /* EAP_SERVER_TNC */
 
+       random_deinit();
+
        eloop_destroy();
 
 #ifndef CONFIG_NATIVE_WINDOWS
index 64180a13ab88d868ff06e437317355f47517ebd6..a30afde1156e584e6adf8675371313d224f3e028 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Random number generator
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,6 +34,7 @@
 #endif /* __linux__ */
 
 #include "utils/common.h"
+#include "utils/eloop.h"
 #include "sha1.h"
 #include "random.h"
 
@@ -53,6 +54,7 @@ static unsigned int pool_pos = 0;
 static u8 dummy_key[20];
 #ifdef __linux__
 static size_t dummy_key_avail = 0;
+static int random_fd = -1;
 #endif /* __linux__ */
 static unsigned int own_pool_ready = 0;
 
@@ -260,3 +262,76 @@ void random_mark_pool_ready(void)
        wpa_printf(MSG_DEBUG, "random: Mark internal entropy pool to be "
                   "ready (count=%u/%u)", own_pool_ready, MIN_READY_MARK);
 }
+
+
+#ifdef __linux__
+
+static void random_close_fd(void)
+{
+       if (random_fd >= 0) {
+               eloop_unregister_read_sock(random_fd);
+               close(random_fd);
+               random_fd = -1;
+       }
+}
+
+
+static void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx)
+{
+       ssize_t res;
+
+       if (dummy_key_avail == sizeof(dummy_key)) {
+               random_close_fd();
+               return;
+       }
+
+       res = read(sock, dummy_key + dummy_key_avail,
+                  sizeof(dummy_key) - dummy_key_avail);
+       if (res < 0) {
+               wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
+                          "%s", strerror(errno));
+               return;
+       }
+
+       wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random",
+                  (unsigned) res,
+                  (unsigned) (sizeof(dummy_key) - dummy_key_avail));
+       dummy_key_avail += res;
+
+       if (dummy_key_avail == sizeof(dummy_key))
+               random_close_fd();
+}
+
+#endif /* __linux__ */
+
+
+void random_init(void)
+{
+#ifdef __linux__
+       if (random_fd >= 0)
+               return;
+
+       random_fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
+       if (random_fd < 0) {
+#ifndef CONFIG_NO_STDOUT_DEBUG
+               int error = errno;
+               perror("open(/dev/random)");
+               wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s",
+                          strerror(error));
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+               return;
+       }
+       wpa_printf(MSG_DEBUG, "random: Trying to read entropy from "
+                  "/dev/random");
+
+       eloop_register_read_sock(random_fd, random_read_fd, NULL, NULL);
+#endif /* __linux__ */
+}
+
+
+void random_deinit(void)
+{
+#ifdef __linux__
+       random_close_fd();
+#endif /* __linux__ */
+}
index 7b62577371f2ff7aecad49adde82b986be8d464e..5dabd2b02f50274bfa290e864c87f11d61341891 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Random number generator
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #define RANDOM_H
 
 #ifdef CONFIG_NO_RANDOM_POOL
+#define random_init() do { } while (0)
+#define random_deinit() do { } while (0)
 #define random_add_randomness(b, l) do { } while (0)
 #define random_get_bytes(b, l) os_get_random((b), (l))
 #define random_pool_ready() 1
 #define random_mark_pool_ready() do { } while (0)
 #else /* CONFIG_NO_RANDOM_POOL */
+void random_init(void);
+void random_deinit(void);
 void random_add_randomness(const void *buf, size_t len);
 int random_get_bytes(void *buf, size_t len);
 int random_pool_ready(void);
index b34bf03955820b1f98a870354bfc9f0a8e9f3646..28b3f0b7009087352d5dd06607667974fec1b1fa 100644 (file)
@@ -19,6 +19,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "crypto/random.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "eap_peer/eap.h"
 #include "eap_server/eap_methods.h"
@@ -2543,6 +2544,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
                return NULL;
        }
 
+       random_init();
+
        global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
        if (global->ctrl_iface == NULL) {
                wpa_supplicant_deinit(global);
@@ -2653,6 +2656,8 @@ void wpa_supplicant_deinit(struct wpa_global *global)
        }
        os_free(global->drv_priv);
 
+       random_deinit();
+
        eloop_destroy();
 
        if (global->params.pid_file) {