From 50b05780c275d2774d40e58d442dd598ae93b7c0 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 15 Jan 2011 14:07:02 +0200 Subject: [PATCH] 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. --- wpa_supplicant/events.c | 8 ++++++++ wpa_supplicant/ibss_rsn.c | 30 ++++++++++++++++++++++++++++++ wpa_supplicant/ibss_rsn.h | 5 +++++ 3 files changed, 43 insertions(+) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index f1fa2cfa7..6b6fcf700 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 fa99c08bd..d4894a5b3 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 11e63ad1b..4e81910df 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 */