aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2011-01-15 12:07:02 (GMT)
committerJouni Malinen <j@w1.fi>2011-01-15 12:07:02 (GMT)
commit50b05780c275d2774d40e58d442dd598ae93b7c0 (patch)
tree7256604aa7d16356afeb6086a40e225c39d884f2
parent2e479416d1bfa584eddf7d335cf969ea6fe1f89c (diff)
downloadhostap-50b05780c275d2774d40e58d442dd598ae93b7c0.zip
hostap-50b05780c275d2774d40e58d442dd598ae93b7c0.tar.gz
hostap-50b05780c275d2774d40e58d442dd598ae93b7c0.tar.bz2
IBSS RSN: Delay setting of the initial TX GTK
The driver may get confused if we set the initial TX GTK before having fully configured and connected to an IBSS, so better delay this operation until the connection (join/start IBSS) has been completed.
-rw-r--r--wpa_supplicant/events.c8
-rw-r--r--wpa_supplicant/ibss_rsn.c30
-rw-r--r--wpa_supplicant/ibss_rsn.h5
3 files changed, 43 insertions, 0 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index f1fa2cf..6b6fcf7 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1310,6 +1310,14 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
/* Set static WEP keys again */
wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
}
+
+#ifdef CONFIG_IBSS_RSN
+ if (wpa_s->current_ssid &&
+ wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE)
+ ibss_rsn_connected(wpa_s->ibss_rsn);
+#endif /* CONFIG_IBSS_RSN */
}
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index fa99c08..d4894a5 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -277,6 +277,15 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
}
}
+ if (ibss_rsn->init_in_progress && key_len <=
+ sizeof(ibss_rsn->init_gtk)) {
+ wpa_printf(MSG_DEBUG, "AUTH: Delay setting of initial TX GTK "
+ "until RSN IBSS is connected");
+ ibss_rsn->init_gtk_idx = idx;
+ os_memcpy(ibss_rsn->init_gtk, key, key_len);
+ return 0;
+ }
+
return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
1, seq, 6, key, key_len);
}
@@ -305,7 +314,9 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
cb.get_psk = auth_get_psk;
cb.set_key = auth_set_key;
+ ibss_rsn->init_in_progress = 1;
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
+ ibss_rsn->init_in_progress = 0;
if (ibss_rsn->auth_group == NULL) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
return -1;
@@ -517,3 +528,22 @@ void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk)
{
os_memcpy(ibss_rsn->psk, psk, PMK_LEN);
}
+
+
+void ibss_rsn_connected(struct ibss_rsn *ibss_rsn)
+{
+ u8 seq[6];
+ wpa_printf(MSG_DEBUG, "RSN: IBSS connected notification");
+ if (ibss_rsn->init_gtk_idx) {
+ wpa_printf(MSG_DEBUG, "RSN: Set initial IBSS TX GTK");
+ os_memset(seq, 0, sizeof(seq));
+ if (wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_CCMP,
+ broadcast_ether_addr,
+ ibss_rsn->init_gtk_idx,
+ 1, seq, sizeof(seq), ibss_rsn->init_gtk,
+ 16) < 0)
+ wpa_printf(MSG_INFO, "RSN: Failed to set IBSS TX GTK");
+ ibss_rsn->init_gtk_idx = 0;
+ os_memset(ibss_rsn->init_gtk, 0, sizeof(ibss_rsn->init_gtk));
+ }
+}
diff --git a/wpa_supplicant/ibss_rsn.h b/wpa_supplicant/ibss_rsn.h
index 11e63ad..4e81910 100644
--- a/wpa_supplicant/ibss_rsn.h
+++ b/wpa_supplicant/ibss_rsn.h
@@ -36,6 +36,10 @@ struct ibss_rsn {
struct wpa_authenticator *auth_group;
struct ibss_rsn_peer *peers;
u8 psk[PMK_LEN];
+
+ int init_in_progress;
+ int init_gtk_idx;
+ u8 init_gtk[16];
};
@@ -45,5 +49,6 @@ int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
const u8 *buf, size_t len);
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);
+void ibss_rsn_connected(struct ibss_rsn *ibss_rsn);
#endif /* IBSS_RSN_H */