aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */