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.
This commit is contained in:
Jouni Malinen 2011-01-15 14:07:02 +02:00
parent 2e479416d1
commit 50b05780c2
3 changed files with 43 additions and 0 deletions

View file

@ -1310,6 +1310,14 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
/* Set static WEP keys again */ /* Set static WEP keys again */
wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); 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 */
} }

View file

@ -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, return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
1, seq, 6, key, key_len); 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.get_psk = auth_get_psk;
cb.set_key = auth_set_key; cb.set_key = auth_set_key;
ibss_rsn->init_in_progress = 1;
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb); ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
ibss_rsn->init_in_progress = 0;
if (ibss_rsn->auth_group == NULL) { if (ibss_rsn->auth_group == NULL) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
return -1; 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); 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));
}
}

View file

@ -36,6 +36,10 @@ struct ibss_rsn {
struct wpa_authenticator *auth_group; struct wpa_authenticator *auth_group;
struct ibss_rsn_peer *peers; struct ibss_rsn_peer *peers;
u8 psk[PMK_LEN]; 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, int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
const u8 *buf, size_t len); const u8 *buf, size_t len);
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk); 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 */ #endif /* IBSS_RSN_H */