aboutsummaryrefslogtreecommitdiffstats
path: root/src/ap
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-11-24 11:08:03 (GMT)
committerJouni Malinen <j@w1.fi>2010-11-24 11:08:03 (GMT)
commit08704cd8859825e70b5a961d9791c1ab25435237 (patch)
tree063afb30f5af307d29bd637fc6c91ad77bfdcf96 /src/ap
parentdbb6ed7e752da8e5d563705afe6a1848d23f4052 (diff)
downloadhostap-08704cd8859825e70b5a961d9791c1ab25435237.zip
hostap-08704cd8859825e70b5a961d9791c1ab25435237.tar.gz
hostap-08704cd8859825e70b5a961d9791c1ab25435237.tar.bz2
hostapd: Verify availability of random data when using WPA/WPA2
On Linux, verify that the kernel entropy pool is capable of providing strong random data before allowing WPA/WPA2 connection to be established. If 20 bytes of data cannot be read from /dev/random, force first two 4-way handshakes to fail while collecting entropy into the internal pool in hostapd. After that, give up on /dev/random and allow the AP to function based on the combination of /dev/urandom and whatever data has been collected into the internal entropy pool.
Diffstat (limited to 'src/ap')
-rw-r--r--src/ap/wpa_auth.c30
-rw-r--r--src/ap/wpa_auth_i.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 851612e..397fa98 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -345,6 +345,12 @@ static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
wpa_group_set_key_len(group, wpa_auth->conf.wpa_group);
+ if (random_pool_ready() != 1) {
+ wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
+ "for secure operations - update keys later when "
+ "the first station connects");
+ }
+
/*
* Set initial GMK/Counter value here. The actual values that will be
* used in negotiations will be set once the first station tries to
@@ -825,6 +831,25 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
return;
}
random_add_randomness(key->key_nonce, WPA_NONCE_LEN);
+ if (sm->group->reject_4way_hs_for_entropy) {
+ /*
+ * The system did not have enough entropy to generate
+ * strong random numbers. Reject the first 4-way
+ * handshake(s) and collect some entropy based on the
+ * information from it. Once enough entropy is
+ * available, the next atempt will trigger GMK/Key
+ * Counter update and the station will be allowed to
+ * continue.
+ */
+ wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to "
+ "collect more entropy for random number "
+ "generation");
+ sm->group->reject_4way_hs_for_entropy = FALSE;
+ random_mark_pool_ready();
+ sm->group->first_sta_seen = FALSE;
+ wpa_sta_disconnect(wpa_auth, sm->addr);
+ return;
+ }
if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length,
&kde) < 0) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
@@ -1465,6 +1490,11 @@ static void wpa_group_first_station(struct wpa_authenticator *wpa_auth,
*/
wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first "
"station");
+ if (random_pool_ready() != 1) {
+ wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
+ "to proceed - reject first 4-way handshake");
+ group->reject_4way_hs_for_entropy = TRUE;
+ }
wpa_group_init_gmk_and_counter(wpa_auth, group);
wpa_gtk_update(wpa_auth, group);
wpa_group_config_group_keys(wpa_auth, group);
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index bc6962f..3173144 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -146,6 +146,7 @@ struct wpa_group {
u8 GNonce[WPA_NONCE_LEN];
Boolean changed;
Boolean first_sta_seen;
+ Boolean reject_4way_hs_for_entropy;
#ifdef CONFIG_IEEE80211W
u8 IGTK[2][WPA_IGTK_LEN];
int GN_igtk, GM_igtk;