[PATCH] Remove os_random() and refactor its callers to use os_get_random(...)

Nick Lowe nick.lowe at lugatech.com
Mon Feb 8 08:58:07 PST 2016


Version without broken whitespace attached. This supersedes the other
uncommitted patch to make this change for the anti-clogging token,
including the same change.

(The justification for the anti-clogging token remains that the RFC
says what it does because the author(s) either must have had a
mistaken notion that there are always issues where an entropy
source/pool can be consumed and did not want to exacerbate that
presumed issue or had notions that there were always significant
performance issues using a source of random entropy. This is not the
case with /dev/urandom in Linux and the entropy sources in other
operating systems that I am aware of.)

Remove os_random() and refactor its callers to use os_get_random(...)

Signed-off-by: Nick Lowe <nick.lowe at lugatech.com>
---
 src/ap/dfs.c                    |  2 +-
 src/ap/ieee802_11.c             |  9 +++------
 src/ap/sta_info.c               |  5 ++++-
 src/ap/wps_hostapd.c            |  3 ++-
 src/eap_server/eap_server_pwd.c |  7 +++++--
 src/pae/ieee802_1x_kay.c        |  4 +++-
 src/utils/os.h                  |  6 ------
 src/utils/os_internal.c         |  6 ------
 src/utils/os_none.c             |  6 ------
 src/utils/os_unix.c             |  6 ------
 src/utils/os_win32.c            |  7 -------
 src/wps/wps.h                   |  2 +-
 src/wps/wps_common.c            |  9 ++++-----
 src/wps/wps_upnp_ssdp.c         | 10 ++++++++--
 wpa_supplicant/ap.c             |  7 +++++--
 wpa_supplicant/ctrl_iface.c     |  3 ++-
 wpa_supplicant/events.c         | 11 ++++-------
 wpa_supplicant/p2p_supplicant.c | 17 ++++++++++++++---
 wpa_supplicant/wpa_supplicant.c |  7 ++++---
 wpa_supplicant/wps_supplicant.c |  5 ++++-
 20 files changed, 64 insertions(+), 68 deletions(-)

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 7273caa..bda23f0 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -450,7 +450,7 @@ dfs_get_valid_channel(struct hostapd_iface *iface,
         return NULL;

     if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
-        _rand = os_random();
+        return NULL;
     chan_idx = _rand % num_available_chandefs;
     dfs_find_channel(iface, &chan, chan_idx, skip_radar);

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index ec6f8a7..7f5738f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -207,16 +207,13 @@ static u16 auth_shared_key(struct hostapd_data
*hapd, struct sta_info *sta,
         if (!sta->challenge) {
             /* Generate a pseudo-random challenge */
             u8 key[8];
-            struct os_time now;
-            int r;
             sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
             if (sta->challenge == NULL)
                 return WLAN_STATUS_UNSPECIFIED_FAILURE;

-            os_get_time(&now);
-            r = os_random();
-            os_memcpy(key, &now.sec, 4);
-            os_memcpy(key + 4, &r, 4);
+            if (os_get_random((u8 *) &key, sizeof(key)) < 0)
+                return WLAN_STATUS_UNSPECIFIED_FAILURE;
+
             rc4_skip(key, sizeof(key), 0,
                  sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
         }
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 3d7c839..50737fd 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -378,7 +378,10 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
          * all stations at the same time if we have lots of associated
          * stations that are idle (but keep re-associating).
          */
-        int fuzz = os_random() % 20;
+        int fuzz = 0;
+        if (os_get_random((u8 *) &fuzz, sizeof(fuzz)) >= 0)
+            fuzz = fuzz % 20;
+
         inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr);
         if (inactive_sec == -1) {
             wpa_msg(hapd->msg_ctx, MSG_DEBUG,
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index ba58f3e..faf38c9 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -1627,7 +1627,8 @@ const char * hostapd_wps_ap_pin_random(struct
hostapd_data *hapd, int timeout)
     unsigned int pin;
     struct wps_ap_pin_data data;

-    pin = wps_generate_pin();
+    if (wps_generate_pin(&pin) < 0)
+        return NULL;
     os_snprintf(data.pin_txt, sizeof(data.pin_txt), "%08u", pin);
     data.timeout = timeout;
     hostapd_wps_for_each(hapd, wps_ap_pin_set, &data);
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index 36ac555..eb3e00f 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -178,8 +178,11 @@ static void eap_pwd_build_id_req(struct eap_sm
*sm, struct eap_pwd_data *data,
         return;
     }

-    /* an lfsr is good enough to generate unpredictable tokens */
-    data->token = os_random();
+    if (os_get_random((u8 *) &data->token, sizeof(data->token)) < 0) {
+        eap_pwd_state(data, FAILURE);
+        return;
+    }
+
     wpabuf_put_be16(data->outbuf, data->group_num);
     wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_RAND_FUNC);
     wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_PRF);
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index ef74430..8053b61 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -3384,7 +3384,9 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay
*kay, struct mka_key_name *ckn,
     wpa_hexdump(MSG_DEBUG, "KaY: Participant created:",
             ckn->name, ckn->len);

-    usecs = os_random() % (MKA_HELLO_TIME * 1000);
+    if (os_get_random((u8 *) &usecs, sizeof(usecs)) < 0)
+        goto fail;
+    usecs = usecs % (MKA_HELLO_TIME * 1000);
     eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
                    participant, NULL);
     participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
diff --git a/src/utils/os.h b/src/utils/os.h
index 9e496fb..08c97e0 100644
--- a/src/utils/os.h
+++ b/src/utils/os.h
@@ -165,12 +165,6 @@ void os_daemonize_terminate(const char *pid_file);
 int os_get_random(unsigned char *buf, size_t len);

 /**
- * os_random - Get pseudo random value (not necessarily very strong)
- * Returns: Pseudo random value
- */
-unsigned long os_random(void);
-
-/**
  * os_rel2abs_path - Get an absolute path for a file
  * @rel_path: Relative path to a file
  * Returns: Absolute path for the file or %NULL on failure
diff --git a/src/utils/os_internal.c b/src/utils/os_internal.c
index ed6eb3c..06b4e7f 100644
--- a/src/utils/os_internal.c
+++ b/src/utils/os_internal.c
@@ -139,12 +139,6 @@ int os_get_random(unsigned char *buf, size_t len)
 }


-unsigned long os_random(void)
-{
-    return random();
-}
-
-
 char * os_rel2abs_path(const char *rel_path)
 {
     char *buf = NULL, *cwd, *ret;
diff --git a/src/utils/os_none.c b/src/utils/os_none.c
index 0c3214d..523292f 100644
--- a/src/utils/os_none.c
+++ b/src/utils/os_none.c
@@ -61,12 +61,6 @@ int os_get_random(unsigned char *buf, size_t len)
 }


-unsigned long os_random(void)
-{
-    return 0;
-}
-
-
 char * os_rel2abs_path(const char *rel_path)
 {
     return NULL; /* strdup(rel_path) can be used here */
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index 8f8dc5b..3ae5f8f 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -266,12 +266,6 @@ int os_get_random(unsigned char *buf, size_t len)
 }


-unsigned long os_random(void)
-{
-    return random();
-}
-
-
 char * os_rel2abs_path(const char *rel_path)
 {
     char *buf = NULL, *cwd, *ret;
diff --git a/src/utils/os_win32.c b/src/utils/os_win32.c
index dea27b9..6adcaf0 100644
--- a/src/utils/os_win32.c
+++ b/src/utils/os_win32.c
@@ -144,13 +144,6 @@ int os_get_random(unsigned char *buf, size_t len)
     return ret ? 0 : -1;
 }

-
-unsigned long os_random(void)
-{
-    return rand();
-}
-
-
 char * os_rel2abs_path(const char *rel_path)
 {
     return _strdup(rel_path);
diff --git a/src/wps/wps.h b/src/wps/wps.h
index ff4dd10..2505d2d 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -837,7 +837,7 @@ int wps_build_credential_wrap(struct wpabuf *msg,

 unsigned int wps_pin_checksum(unsigned int pin);
 unsigned int wps_pin_valid(unsigned int pin);
-unsigned int wps_generate_pin(void);
+int wps_generate_pin(unsigned int *pin);
 int wps_pin_str_valid(const char *pin);
 void wps_free_pending_msgs(struct upnp_pending_message *msgs);

diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c
index 88f85fe..1ee9eb9 100644
--- a/src/wps/wps_common.c
+++ b/src/wps/wps_common.c
@@ -235,20 +235,19 @@ unsigned int wps_pin_valid(unsigned int pin)
  * wps_generate_pin - Generate a random PIN
  * Returns: Eight digit PIN (i.e., including the checksum digit)
  */
-unsigned int wps_generate_pin(void)
+int wps_generate_pin(unsigned int *pin)
 {
     unsigned int val;

     /* Generate seven random digits for the PIN */
     if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) {
-        struct os_time now;
-        os_get_time(&now);
-        val = os_random() ^ now.sec ^ now.usec;
+        return -1;
     }
     val %= 10000000;

     /* Append checksum digit */
-    return val * 10 + wps_pin_checksum(val);
+    *pin = val * 10 + wps_pin_checksum(val);
+    return 0;
 }


diff --git a/src/wps/wps_upnp_ssdp.c b/src/wps/wps_upnp_ssdp.c
index 968fc03..2b6da2b 100644
--- a/src/wps/wps_upnp_ssdp.c
+++ b/src/wps/wps_upnp_ssdp.c
@@ -354,7 +354,10 @@ int advertisement_state_machine_start(struct
upnp_wps_device_sm *sm)
     /* (other fields not used here) */

     /* First timeout should be random interval < 100 msec */
-    next_timeout_msec = (100 * (os_random() & 0xFF)) >> 8;
+    if (os_get_random((u8 *) &next_timeout_msec,
+           sizeof(next_timeout_msec)) < 0)
+        return -1;
+    next_timeout_msec = (100 * (next_timeout_msec & 0xFF)) >> 8;
     return eloop_register_timeout(0, next_timeout_msec,
                       advertisement_state_machine_handler,
                       NULL, sm);
@@ -475,7 +478,10 @@ static void
msearchreply_state_machine_start(struct upnp_wps_device_sm *sm,
     a->state = 0;
     os_memcpy(&a->client, client, sizeof(*client));
     /* Wait time depending on MX value */
-    next_timeout_msec = (1000 * mx * (os_random() & 0xFF)) >> 8;
+    if (os_get_random((u8 *) &next_timeout_msec,
+            sizeof(next_timeout_msec)) < 0)
+        goto fail;
+    next_timeout_msec = (1000 * mx * (next_timeout_msec & 0xFF)) >> 8;
     next_timeout_sec = next_timeout_msec / 1000;
     next_timeout_msec = next_timeout_msec % 1000;
     if (eloop_register_timeout(next_timeout_sec, next_timeout_msec,
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 98b9596..1a0fbc4 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -913,7 +913,9 @@ int wpa_supplicant_ap_wps_pin(struct
wpa_supplicant *wpa_s, const u8 *bssid,
         return -1;

     if (pin == NULL) {
-        unsigned int rpin = wps_generate_pin();
+        unsigned int rpin;
+        if (wps_generate_pin(&rpin) < 0)
+            return -1;
         ret_len = os_snprintf(buf, buflen, "%08d", rpin);
         if (os_snprintf_error(buflen, ret_len))
             return -1;
@@ -979,7 +981,8 @@ const char * wpas_wps_ap_pin_random(struct
wpa_supplicant *wpa_s, int timeout)
     if (wpa_s->ap_iface == NULL)
         return NULL;
     hapd = wpa_s->ap_iface->bss[0];
-    pin = wps_generate_pin();
+    if (wps_generate_pin(&pin) < 0)
+        return NULL;
     os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
     os_free(hapd->conf->ap_pin);
     hapd->conf->ap_pin = os_strdup(pin_txt);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index b3d6246..7a6f4c9 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -956,7 +956,8 @@ static int
wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
     if (os_strcmp(cmd, "any") == 0)
         _bssid = NULL;
     else if (os_strcmp(cmd, "get") == 0) {
-        ret = wps_generate_pin();
+        if (wps_generate_pin(&pin) < 0)
+            return -1;
         goto done;
     } else if (hwaddr_aton(cmd, bssid)) {
         wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2870e89..fabb8fd 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2622,13 +2622,10 @@
wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
              * the information on whether a frame resulted in a MIC
              * failure.
              */
-            u8 rval[4];
-            int sec;
+            int sec = 60;

-            if (os_get_random(rval, sizeof(rval)) < 0)
-                sec = os_random() % 60;
-            else
-                sec = WPA_GET_BE32(rval) % 60;
+            if (os_get_random(sec, sizeof(sec)) >= 0)
+                sec = sec % 60;
             wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error "
                 "report %d seconds", sec);
             wpa_s->pending_mic_error_report = 1;
@@ -2637,7 +2634,7 @@ wpa_supplicant_event_michael_mic_failure(struct
wpa_supplicant *wpa_s,
                 wpa_supplicant_delayed_mic_error_report,
                 wpa_s, NULL);
             eloop_register_timeout(
-                sec, os_random() % 1000000,
+                sec, 0,
                 wpa_supplicant_delayed_mic_error_report,
                 wpa_s, NULL);
         } else {
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 9b36b63..2de45a9 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2576,7 +2576,12 @@ static void wpas_prov_disc_req(void *ctx, const
u8 *peer, u16 config_methods,
     params[sizeof(params) - 1] = '\0';

     if (config_methods & WPS_CONFIG_DISPLAY) {
-        generated_pin = wps_generate_pin();
+        if (wps_generate_pin(&generated_pin) < 0) {
+            wpa_printf(MSG_DEBUG, "P2P: Could not generate pin");
+            wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
+                    P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
+            return;
+        }
         wpas_prov_disc_local_display(wpa_s, peer, params,
                          generated_pin);
     } else if (config_methods & WPS_CONFIG_KEYPAD)
@@ -2621,7 +2626,12 @@ static void wpas_prov_disc_resp(void *ctx,
const u8 *peer, u16 config_methods)
     if (config_methods & WPS_CONFIG_DISPLAY)
         wpas_prov_disc_local_keypad(wpa_s, peer, params);
     else if (config_methods & WPS_CONFIG_KEYPAD) {
-        generated_pin = wps_generate_pin();
+        if (wps_generate_pin(&generated_pin) < 0) {
+            wpa_printf(MSG_DEBUG, "P2P: Could not generate pin");
+            wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
+                    P2P_PROV_DISC_INFO_UNAVAILABLE, 0, 0);
+            return;
+        }
         wpas_prov_disc_local_display(wpa_s, peer, params,
                          generated_pin);
     } else if (config_methods & WPS_CONFIG_PUSHBUTTON)
@@ -5364,7 +5374,8 @@ int wpas_p2p_connect(struct wpa_supplicant
*wpa_s, const u8 *peer_addr,
     if (pin)
         os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
     else if (wps_method == WPS_PIN_DISPLAY) {
-        ret = wps_generate_pin();
+        if (wps_generate_pin(&ret) < 0)
+            return -1;
         res = os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin),
                   "%08d", ret);
         if (os_snprintf_error(sizeof(wpa_s->p2p_pin), res))
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index c3c1f14..c21dc5f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -5593,7 +5593,7 @@ int
wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant
*wpa_s,

 int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
 {
-    int i;
+    int i, r;
     unsigned int drv_enc;

     if (wpa_s->p2p_mgmt)
@@ -5710,8 +5710,9 @@ void wpas_auth_failed(struct wpa_supplicant
*wpa_s, char *reason)
         dur = 10;

     if (ssid->auth_failures > 1 &&
-        wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
-        dur += os_random() % (ssid->auth_failures * 10);
+            wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt) &&
+            os_get_random((u8 *) &r, sizeof(r)) >= 0)
+        dur += r % (ssid->auth_failures * 10);

     os_get_reltime(&now);
     if (now.sec + dur <= ssid->disabled_until.sec)
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 5c674b2..098d4c2 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1228,7 +1228,10 @@ static int wpas_wps_start_dev_pw(struct
wpa_supplicant *wpa_s,
         os_snprintf(val, sizeof(val), "\"dev_pw_id=%u%s\"",
                 dev_pw_id, hash);
     } else {
-        rpin = wps_generate_pin();
+        if (wps_generate_pin(&rpin) < 0) {
+            wpa_printf(MSG_DEBUG, "WPS: Could not generate pin");
+            return -1;
+        }
         os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u%s\"",
                 rpin, dev_pw_id, hash);
     }
-- 
2.5.0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Remove-os_random-and-refactor-its-callers-to-use-os_.patch
Type: text/x-patch
Size: 15280 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20160208/a3f28875/attachment-0001.bin>


More information about the Hostap mailing list