2 * wpa_supplicant - IBSS RSN
3 * Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "common/wpa_ctrl.h"
13 #include "utils/eloop.h"
14 #include "l2_packet/l2_packet.h"
15 #include "rsn_supp/wpa.h"
16 #include "rsn_supp/wpa_ie.h"
17 #include "ap/wpa_auth.h"
18 #include "wpa_supplicant_i.h"
20 #include "common/ieee802_11_defs.h"
24 static void ibss_rsn_auth_timeout(void *eloop_ctx
, void *timeout_ctx
);
27 static struct ibss_rsn_peer
* ibss_rsn_get_peer(struct ibss_rsn
*ibss_rsn
,
30 struct ibss_rsn_peer
*peer
;
32 for (peer
= ibss_rsn
->peers
; peer
; peer
= peer
->next
)
33 if (os_memcmp(addr
, peer
->addr
, ETH_ALEN
) == 0)
39 static void ibss_rsn_free(struct ibss_rsn_peer
*peer
)
41 eloop_cancel_timeout(ibss_rsn_auth_timeout
, peer
, NULL
);
42 wpa_auth_sta_deinit(peer
->auth
);
43 wpa_sm_deinit(peer
->supp
);
48 static void supp_set_state(void *ctx
, enum wpa_states state
)
50 struct ibss_rsn_peer
*peer
= ctx
;
51 peer
->supp_state
= state
;
55 static enum wpa_states
supp_get_state(void *ctx
)
57 struct ibss_rsn_peer
*peer
= ctx
;
58 return peer
->supp_state
;
62 static int supp_ether_send(void *ctx
, const u8
*dest
, u16 proto
, const u8
*buf
,
65 struct ibss_rsn_peer
*peer
= ctx
;
66 struct wpa_supplicant
*wpa_s
= peer
->ibss_rsn
->wpa_s
;
67 int encrypt
= peer
->authentication_status
& IBSS_RSN_REPORTED_PTK
;
69 wpa_printf(MSG_DEBUG
, "SUPP: %s(dest=" MACSTR
70 " proto=0x%04x len=%lu no_encrypt=%d)",
71 __func__
, MAC2STR(dest
), proto
, (unsigned long) len
,
74 if (wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_CONTROL_PORT
)
75 return wpa_drv_tx_control_port(wpa_s
, dest
, proto
, buf
, len
,
79 return l2_packet_send(wpa_s
->l2
, dest
, proto
, buf
, len
);
85 static u8
* supp_alloc_eapol(void *ctx
, u8 type
, const void *data
,
86 u16 data_len
, size_t *msg_len
, void **data_pos
)
88 struct ieee802_1x_hdr
*hdr
;
90 wpa_printf(MSG_DEBUG
, "SUPP: %s(type=%d data_len=%d)",
91 __func__
, type
, data_len
);
93 *msg_len
= sizeof(*hdr
) + data_len
;
94 hdr
= os_malloc(*msg_len
);
100 hdr
->length
= host_to_be16(data_len
);
103 os_memcpy(hdr
+ 1, data
, data_len
);
105 os_memset(hdr
+ 1, 0, data_len
);
114 static int supp_get_beacon_ie(void *ctx
)
116 struct ibss_rsn_peer
*peer
= ctx
;
118 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
119 /* TODO: get correct RSN IE */
120 wpa_sm_set_ap_rsnxe(peer
->supp
, NULL
, 0);
121 return wpa_sm_set_ap_rsn_ie(peer
->supp
,
122 (u8
*) "\x30\x14\x01\x00"
124 "\x01\x00\x00\x0f\xac\x04"
125 "\x01\x00\x00\x0f\xac\x02"
130 static void ibss_check_rsn_completed(struct ibss_rsn_peer
*peer
)
132 struct wpa_supplicant
*wpa_s
= peer
->ibss_rsn
->wpa_s
;
134 if ((peer
->authentication_status
&
135 (IBSS_RSN_SET_PTK_SUPP
| IBSS_RSN_SET_PTK_AUTH
)) !=
136 (IBSS_RSN_SET_PTK_SUPP
| IBSS_RSN_SET_PTK_AUTH
))
138 if (peer
->authentication_status
& IBSS_RSN_REPORTED_PTK
)
140 peer
->authentication_status
|= IBSS_RSN_REPORTED_PTK
;
141 wpa_msg(wpa_s
, MSG_INFO
, IBSS_RSN_COMPLETED MACSTR
,
142 MAC2STR(peer
->addr
));
146 static int supp_set_key(void *ctx
, enum wpa_alg alg
,
147 const u8
*addr
, int key_idx
, int set_tx
,
148 const u8
*seq
, size_t seq_len
,
149 const u8
*key
, size_t key_len
, enum key_flag key_flag
)
151 struct ibss_rsn_peer
*peer
= ctx
;
153 wpa_printf(MSG_DEBUG
, "SUPP: %s(alg=%d addr=" MACSTR
" key_idx=%d "
155 __func__
, alg
, MAC2STR(addr
), key_idx
, set_tx
);
156 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - seq", seq
, seq_len
);
157 wpa_hexdump_key(MSG_DEBUG
, "SUPP: set_key - key", key
, key_len
);
160 peer
->authentication_status
|= IBSS_RSN_SET_PTK_SUPP
;
161 ibss_check_rsn_completed(peer
);
163 * In IBSS RSN, the pairwise key from the 4-way handshake
164 * initiated by the peer with highest MAC address is used.
166 if (os_memcmp(peer
->ibss_rsn
->wpa_s
->own_addr
, peer
->addr
,
168 wpa_printf(MSG_DEBUG
, "SUPP: Do not use this PTK");
173 if (is_broadcast_ether_addr(addr
))
175 return wpa_drv_set_key(peer
->ibss_rsn
->wpa_s
, alg
, addr
, key_idx
,
176 set_tx
, seq
, seq_len
, key
, key_len
, key_flag
);
180 static void * supp_get_network_ctx(void *ctx
)
182 struct ibss_rsn_peer
*peer
= ctx
;
183 return wpa_supplicant_get_ssid(peer
->ibss_rsn
->wpa_s
);
187 static int supp_mlme_setprotection(void *ctx
, const u8
*addr
,
188 int protection_type
, int key_type
)
190 wpa_printf(MSG_DEBUG
, "SUPP: %s(addr=" MACSTR
" protection_type=%d "
192 __func__
, MAC2STR(addr
), protection_type
, key_type
);
197 static void supp_cancel_auth_timeout(void *ctx
)
199 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
203 static void supp_deauthenticate(void *ctx
, u16 reason_code
)
205 wpa_printf(MSG_DEBUG
, "SUPP: %s (TODO)", __func__
);
209 static void supp_reconnect(void *ctx
)
211 wpa_printf(MSG_DEBUG
, "SUPP: %s (TODO)", __func__
);
215 static int ibss_rsn_supp_init(struct ibss_rsn_peer
*peer
, const u8
*own_addr
,
218 struct wpa_sm_ctx
*ctx
= os_zalloc(sizeof(*ctx
));
223 ctx
->msg_ctx
= peer
->ibss_rsn
->wpa_s
;
224 ctx
->set_state
= supp_set_state
;
225 ctx
->get_state
= supp_get_state
;
226 ctx
->ether_send
= supp_ether_send
;
227 ctx
->get_beacon_ie
= supp_get_beacon_ie
;
228 ctx
->alloc_eapol
= supp_alloc_eapol
;
229 ctx
->set_key
= supp_set_key
;
230 ctx
->get_network_ctx
= supp_get_network_ctx
;
231 ctx
->mlme_setprotection
= supp_mlme_setprotection
;
232 ctx
->cancel_auth_timeout
= supp_cancel_auth_timeout
;
233 ctx
->deauthenticate
= supp_deauthenticate
;
234 ctx
->reconnect
= supp_reconnect
;
235 peer
->supp
= wpa_sm_init(ctx
);
236 if (peer
->supp
== NULL
) {
237 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_init() failed");
242 wpa_sm_set_own_addr(peer
->supp
, own_addr
);
243 wpa_sm_set_param(peer
->supp
, WPA_PARAM_RSN_ENABLED
, 1);
244 wpa_sm_set_param(peer
->supp
, WPA_PARAM_PROTO
, WPA_PROTO_RSN
);
245 wpa_sm_set_param(peer
->supp
, WPA_PARAM_PAIRWISE
, WPA_CIPHER_CCMP
);
246 wpa_sm_set_param(peer
->supp
, WPA_PARAM_GROUP
, WPA_CIPHER_CCMP
);
247 wpa_sm_set_param(peer
->supp
, WPA_PARAM_KEY_MGMT
, WPA_KEY_MGMT_PSK
);
248 wpa_sm_set_pmk(peer
->supp
, psk
, PMK_LEN
, NULL
, NULL
);
250 peer
->supp_ie_len
= sizeof(peer
->supp_ie
);
251 if (wpa_sm_set_assoc_wpa_ie_default(peer
->supp
, peer
->supp_ie
,
252 &peer
->supp_ie_len
) < 0) {
253 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
258 wpa_sm_notify_assoc(peer
->supp
, peer
->addr
);
264 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
268 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
271 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
275 static const u8
* auth_get_psk(void *ctx
, const u8
*addr
,
276 const u8
*p2p_dev_addr
, const u8
*prev_psk
,
277 size_t *psk_len
, int *vlan_id
)
279 struct ibss_rsn
*ibss_rsn
= ctx
;
285 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
286 __func__
, MAC2STR(addr
), prev_psk
);
289 return ibss_rsn
->psk
;
293 static int auth_send_eapol(void *ctx
, const u8
*addr
, const u8
*data
,
294 size_t data_len
, int encrypt
)
296 struct ibss_rsn
*ibss_rsn
= ctx
;
297 struct wpa_supplicant
*wpa_s
= ibss_rsn
->wpa_s
;
299 wpa_printf(MSG_DEBUG
, "AUTH: %s(addr=" MACSTR
" data_len=%lu "
301 __func__
, MAC2STR(addr
), (unsigned long) data_len
, encrypt
);
303 if (wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_CONTROL_PORT
)
304 return wpa_drv_tx_control_port(wpa_s
, addr
, ETH_P_EAPOL
,
305 data
, data_len
, !encrypt
);
308 return l2_packet_send(wpa_s
->l2
, addr
, ETH_P_EAPOL
, data
,
315 static int auth_set_key(void *ctx
, int vlan_id
, enum wpa_alg alg
,
316 const u8
*addr
, int idx
, u8
*key
, size_t key_len
,
317 enum key_flag key_flag
)
319 struct ibss_rsn
*ibss_rsn
= ctx
;
322 os_memset(seq
, 0, sizeof(seq
));
325 wpa_printf(MSG_DEBUG
, "AUTH: %s(alg=%d addr=" MACSTR
327 __func__
, alg
, MAC2STR(addr
), idx
);
329 wpa_printf(MSG_DEBUG
, "AUTH: %s(alg=%d key_idx=%d)",
332 wpa_hexdump_key(MSG_DEBUG
, "AUTH: set_key - key", key
, key_len
);
336 struct ibss_rsn_peer
*peer
;
337 peer
= ibss_rsn_get_peer(ibss_rsn
, addr
);
339 peer
->authentication_status
|=
340 IBSS_RSN_SET_PTK_AUTH
;
341 ibss_check_rsn_completed(peer
);
345 * In IBSS RSN, the pairwise key from the 4-way handshake
346 * initiated by the peer with highest MAC address is used.
349 os_memcmp(ibss_rsn
->wpa_s
->own_addr
, addr
, ETH_ALEN
) < 0) {
350 wpa_printf(MSG_DEBUG
, "AUTH: Do not use this PTK");
355 return wpa_drv_set_key(ibss_rsn
->wpa_s
, alg
, addr
, idx
,
356 1, seq
, 6, key
, key_len
, key_flag
);
360 static void ibss_rsn_disconnect(void *ctx
, const u8
*addr
, u16 reason
)
362 struct ibss_rsn
*ibss_rsn
= ctx
;
363 wpa_drv_sta_deauth(ibss_rsn
->wpa_s
, addr
, reason
);
367 static int auth_for_each_sta(void *ctx
, int (*cb
)(struct wpa_state_machine
*sm
,
371 struct ibss_rsn
*ibss_rsn
= ctx
;
372 struct ibss_rsn_peer
*peer
;
374 wpa_printf(MSG_DEBUG
, "AUTH: for_each_sta");
376 for (peer
= ibss_rsn
->peers
; peer
; peer
= peer
->next
) {
377 if (peer
->auth
&& cb(peer
->auth
, cb_ctx
))
385 static void ibss_set_sta_authorized(struct ibss_rsn
*ibss_rsn
,
386 struct ibss_rsn_peer
*peer
, int authorized
)
391 res
= wpa_drv_sta_set_flags(ibss_rsn
->wpa_s
, peer
->addr
,
393 WPA_STA_AUTHORIZED
, ~0);
394 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" authorizing port",
395 MAC2STR(peer
->addr
));
397 res
= wpa_drv_sta_set_flags(ibss_rsn
->wpa_s
, peer
->addr
,
398 0, 0, ~WPA_STA_AUTHORIZED
);
399 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" unauthorizing port",
400 MAC2STR(peer
->addr
));
403 if (res
&& errno
!= ENOENT
) {
404 wpa_printf(MSG_DEBUG
, "Could not set station " MACSTR
" flags "
405 "for kernel driver (errno=%d)",
406 MAC2STR(peer
->addr
), errno
);
411 static void auth_set_eapol(void *ctx
, const u8
*addr
,
412 wpa_eapol_variable var
, int value
)
414 struct ibss_rsn
*ibss_rsn
= ctx
;
415 struct ibss_rsn_peer
*peer
= ibss_rsn_get_peer(ibss_rsn
, addr
);
421 case WPA_EAPOL_authorized
:
422 ibss_set_sta_authorized(ibss_rsn
, peer
, value
);
425 /* do not handle any other event */
426 wpa_printf(MSG_DEBUG
, "AUTH: eapol event not handled %d", var
);
432 static int ibss_rsn_auth_init_group(struct ibss_rsn
*ibss_rsn
,
433 const u8
*own_addr
, struct wpa_ssid
*ssid
)
435 struct wpa_auth_config conf
;
436 static const struct wpa_auth_callbacks cb
= {
437 .logger
= auth_logger
,
438 .set_eapol
= auth_set_eapol
,
439 .send_eapol
= auth_send_eapol
,
440 .get_psk
= auth_get_psk
,
441 .set_key
= auth_set_key
,
442 .for_each_sta
= auth_for_each_sta
,
443 .disconnect
= ibss_rsn_disconnect
,
446 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
448 os_memset(&conf
, 0, sizeof(conf
));
450 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
451 conf
.wpa_pairwise
= WPA_CIPHER_CCMP
;
452 conf
.rsn_pairwise
= WPA_CIPHER_CCMP
;
453 conf
.wpa_group
= WPA_CIPHER_CCMP
;
454 conf
.eapol_version
= 2;
455 conf
.wpa_group_rekey
= ssid
->group_rekey
? ssid
->group_rekey
: 600;
456 conf
.wpa_group_update_count
= 4;
457 conf
.wpa_pairwise_update_count
= 4;
459 ibss_rsn
->auth_group
= wpa_init(own_addr
, &conf
, &cb
, ibss_rsn
);
460 if (ibss_rsn
->auth_group
== NULL
) {
461 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
465 wpa_init_keys(ibss_rsn
->auth_group
);
471 static int ibss_rsn_auth_init(struct ibss_rsn
*ibss_rsn
,
472 struct ibss_rsn_peer
*peer
)
474 peer
->auth
= wpa_auth_sta_init(ibss_rsn
->auth_group
, peer
->addr
, NULL
);
475 if (peer
->auth
== NULL
) {
476 wpa_printf(MSG_DEBUG
, "AUTH: wpa_auth_sta_init() failed");
480 /* TODO: get peer RSN IE with Probe Request */
481 if (wpa_validate_wpa_ie(ibss_rsn
->auth_group
, peer
->auth
, 0,
482 (u8
*) "\x30\x14\x01\x00"
484 "\x01\x00\x00\x0f\xac\x04"
485 "\x01\x00\x00\x0f\xac\x02"
486 "\x00\x00", 22, NULL
, 0, NULL
, 0, NULL
, 0) !=
488 wpa_printf(MSG_DEBUG
, "AUTH: wpa_validate_wpa_ie() failed");
492 if (wpa_auth_sm_event(peer
->auth
, WPA_ASSOC
))
495 if (wpa_auth_sta_associated(ibss_rsn
->auth_group
, peer
->auth
))
502 static int ibss_rsn_send_auth(struct ibss_rsn
*ibss_rsn
, const u8
*da
, int seq
)
504 struct ieee80211_mgmt auth
;
505 const size_t auth_length
= IEEE80211_HDRLEN
+ sizeof(auth
.u
.auth
);
506 struct wpa_supplicant
*wpa_s
= ibss_rsn
->wpa_s
;
508 os_memset(&auth
, 0, sizeof(auth
));
510 auth
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
512 os_memcpy(auth
.da
, da
, ETH_ALEN
);
513 os_memcpy(auth
.sa
, wpa_s
->own_addr
, ETH_ALEN
);
514 os_memcpy(auth
.bssid
, wpa_s
->bssid
, ETH_ALEN
);
516 auth
.u
.auth
.auth_alg
= host_to_le16(WLAN_AUTH_OPEN
);
517 auth
.u
.auth
.auth_transaction
= host_to_le16(seq
);
518 auth
.u
.auth
.status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
520 wpa_printf(MSG_DEBUG
, "RSN: IBSS TX Auth frame (SEQ %d) to " MACSTR
,
523 return wpa_drv_send_mlme(wpa_s
, (u8
*) &auth
, auth_length
, 0, 0, 0);
527 static int ibss_rsn_is_auth_started(struct ibss_rsn_peer
* peer
)
529 return peer
->authentication_status
&
530 (IBSS_RSN_AUTH_BY_US
| IBSS_RSN_AUTH_EAPOL_BY_US
);
534 static struct ibss_rsn_peer
*
535 ibss_rsn_peer_init(struct ibss_rsn
*ibss_rsn
, const u8
*addr
)
537 struct ibss_rsn_peer
*peer
;
538 if (ibss_rsn
== NULL
)
541 peer
= ibss_rsn_get_peer(ibss_rsn
, addr
);
543 wpa_printf(MSG_DEBUG
, "RSN: IBSS Supplicant for peer "MACSTR
544 " already running", MAC2STR(addr
));
548 wpa_printf(MSG_DEBUG
, "RSN: Starting IBSS Supplicant for peer "MACSTR
,
551 peer
= os_zalloc(sizeof(*peer
));
553 wpa_printf(MSG_DEBUG
, "RSN: Could not allocate memory.");
557 peer
->ibss_rsn
= ibss_rsn
;
558 os_memcpy(peer
->addr
, addr
, ETH_ALEN
);
559 peer
->authentication_status
= IBSS_RSN_AUTH_NOT_AUTHENTICATED
;
561 if (ibss_rsn_supp_init(peer
, ibss_rsn
->wpa_s
->own_addr
,
562 ibss_rsn
->psk
) < 0) {
567 peer
->next
= ibss_rsn
->peers
;
568 ibss_rsn
->peers
= peer
;
574 static void ibss_rsn_auth_timeout(void *eloop_ctx
, void *timeout_ctx
)
576 struct ibss_rsn_peer
*peer
= eloop_ctx
;
579 * Assume peer does not support Authentication exchange or the frame was
580 * lost somewhere - start EAPOL Authenticator.
582 wpa_printf(MSG_DEBUG
,
583 "RSN: Timeout on waiting Authentication frame response from "
584 MACSTR
" - start authenticator", MAC2STR(peer
->addr
));
586 peer
->authentication_status
|= IBSS_RSN_AUTH_BY_US
;
587 ibss_rsn_auth_init(peer
->ibss_rsn
, peer
);
591 int ibss_rsn_start(struct ibss_rsn
*ibss_rsn
, const u8
*addr
)
593 struct ibss_rsn_peer
*peer
;
599 /* if the peer already exists, exit immediately */
600 peer
= ibss_rsn_get_peer(ibss_rsn
, addr
);
604 peer
= ibss_rsn_peer_init(ibss_rsn
, addr
);
608 /* Open Authentication: send first Authentication frame */
609 res
= ibss_rsn_send_auth(ibss_rsn
, addr
, 1);
612 * The driver may not support Authentication frame exchange in
613 * IBSS. Ignore authentication and go through EAPOL exchange.
615 peer
->authentication_status
|= IBSS_RSN_AUTH_BY_US
;
616 return ibss_rsn_auth_init(ibss_rsn
, peer
);
618 os_get_reltime(&peer
->own_auth_tx
);
619 eloop_register_timeout(1, 0, ibss_rsn_auth_timeout
, peer
, NULL
);
626 static int ibss_rsn_peer_authenticated(struct ibss_rsn
*ibss_rsn
,
627 struct ibss_rsn_peer
*peer
, int reason
)
631 if (ibss_rsn
== NULL
|| peer
== NULL
)
634 already_started
= ibss_rsn_is_auth_started(peer
);
635 peer
->authentication_status
|= reason
;
637 if (already_started
) {
638 wpa_printf(MSG_DEBUG
, "RSN: IBSS Authenticator already "
639 "started for peer " MACSTR
, MAC2STR(peer
->addr
));
643 wpa_printf(MSG_DEBUG
, "RSN: Starting IBSS Authenticator "
644 "for now-authenticated peer " MACSTR
, MAC2STR(peer
->addr
));
646 return ibss_rsn_auth_init(ibss_rsn
, peer
);
650 void ibss_rsn_stop(struct ibss_rsn
*ibss_rsn
, const u8
*peermac
)
652 struct ibss_rsn_peer
*peer
, *prev
;
654 if (ibss_rsn
== NULL
)
657 if (peermac
== NULL
) {
658 /* remove all peers */
659 wpa_printf(MSG_DEBUG
, "%s: Remove all peers", __func__
);
660 peer
= ibss_rsn
->peers
;
665 ibss_rsn
->peers
= peer
;
668 /* remove specific peer */
669 wpa_printf(MSG_DEBUG
, "%s: Remove specific peer " MACSTR
,
670 __func__
, MAC2STR(peermac
));
672 for (prev
= NULL
, peer
= ibss_rsn
->peers
; peer
!= NULL
;
673 prev
= peer
, peer
= peer
->next
) {
674 if (os_memcmp(peermac
, peer
->addr
, ETH_ALEN
) == 0) {
676 ibss_rsn
->peers
= peer
->next
;
678 prev
->next
= peer
->next
;
680 wpa_printf(MSG_DEBUG
, "%s: Successfully "
681 "removed a specific peer",
690 struct ibss_rsn
* ibss_rsn_init(struct wpa_supplicant
*wpa_s
,
691 struct wpa_ssid
*ssid
)
693 struct ibss_rsn
*ibss_rsn
;
695 ibss_rsn
= os_zalloc(sizeof(*ibss_rsn
));
696 if (ibss_rsn
== NULL
)
698 ibss_rsn
->wpa_s
= wpa_s
;
700 if (ibss_rsn_auth_init_group(ibss_rsn
, wpa_s
->own_addr
, ssid
) < 0) {
701 ibss_rsn_deinit(ibss_rsn
);
709 void ibss_rsn_deinit(struct ibss_rsn
*ibss_rsn
)
711 struct ibss_rsn_peer
*peer
, *prev
;
713 if (ibss_rsn
== NULL
)
716 peer
= ibss_rsn
->peers
;
723 if (ibss_rsn
->auth_group
)
724 wpa_deinit(ibss_rsn
->auth_group
);
730 static int ibss_rsn_eapol_dst_supp(const u8
*buf
, size_t len
)
732 const struct ieee802_1x_hdr
*hdr
;
733 const struct wpa_eapol_key
*key
;
737 /* TODO: Support other EAPOL packets than just EAPOL-Key */
739 if (len
< sizeof(*hdr
) + sizeof(*key
))
742 hdr
= (const struct ieee802_1x_hdr
*) buf
;
743 key
= (const struct wpa_eapol_key
*) (hdr
+ 1);
744 plen
= be_to_host16(hdr
->length
);
746 if (hdr
->version
< EAPOL_VERSION
) {
747 /* TODO: backwards compatibility */
749 if (hdr
->type
!= IEEE802_1X_TYPE_EAPOL_KEY
) {
750 wpa_printf(MSG_DEBUG
, "RSN: EAPOL frame (type %u) discarded, "
751 "not a Key frame", hdr
->type
);
754 if (plen
> len
- sizeof(*hdr
) || plen
< sizeof(*key
)) {
755 wpa_printf(MSG_DEBUG
, "RSN: EAPOL frame payload size %lu "
756 "invalid (frame size %lu)",
757 (unsigned long) plen
, (unsigned long) len
);
761 if (key
->type
!= EAPOL_KEY_TYPE_RSN
) {
762 wpa_printf(MSG_DEBUG
, "RSN: EAPOL-Key type (%d) unknown, "
763 "discarded", key
->type
);
767 key_info
= WPA_GET_BE16(key
->key_info
);
769 return !!(key_info
& WPA_KEY_INFO_ACK
);
773 static int ibss_rsn_process_rx_eapol(struct ibss_rsn
*ibss_rsn
,
774 struct ibss_rsn_peer
*peer
,
775 const u8
*buf
, size_t len
)
780 supp
= ibss_rsn_eapol_dst_supp(buf
, len
);
784 tmp
= os_memdup(buf
, len
);
788 peer
->authentication_status
|= IBSS_RSN_AUTH_EAPOL_BY_PEER
;
789 wpa_printf(MSG_DEBUG
, "RSN: IBSS RX EAPOL for Supplicant from "
790 MACSTR
, MAC2STR(peer
->addr
));
791 wpa_sm_rx_eapol(peer
->supp
, peer
->addr
, tmp
, len
);
793 if (ibss_rsn_is_auth_started(peer
) == 0) {
794 wpa_printf(MSG_DEBUG
, "RSN: IBSS EAPOL for "
795 "Authenticator dropped as " MACSTR
" is not "
796 "authenticated", MAC2STR(peer
->addr
));
801 wpa_printf(MSG_DEBUG
, "RSN: IBSS RX EAPOL for Authenticator "
802 "from "MACSTR
, MAC2STR(peer
->addr
));
803 wpa_receive(ibss_rsn
->auth_group
, peer
->auth
, tmp
, len
);
811 int ibss_rsn_rx_eapol(struct ibss_rsn
*ibss_rsn
, const u8
*src_addr
,
812 const u8
*buf
, size_t len
)
814 struct ibss_rsn_peer
*peer
;
816 if (ibss_rsn
== NULL
)
819 peer
= ibss_rsn_get_peer(ibss_rsn
, src_addr
);
821 return ibss_rsn_process_rx_eapol(ibss_rsn
, peer
, buf
, len
);
823 if (ibss_rsn_eapol_dst_supp(buf
, len
) > 0) {
825 * Create new IBSS peer based on an EAPOL message from the peer
828 peer
= ibss_rsn_peer_init(ibss_rsn
, src_addr
);
832 /* assume the peer is authenticated already */
833 wpa_printf(MSG_DEBUG
, "RSN: IBSS Not using IBSS Auth for peer "
834 MACSTR
, MAC2STR(src_addr
));
835 ibss_rsn_peer_authenticated(ibss_rsn
, peer
,
836 IBSS_RSN_AUTH_EAPOL_BY_US
);
838 return ibss_rsn_process_rx_eapol(ibss_rsn
, ibss_rsn
->peers
,
845 void ibss_rsn_set_psk(struct ibss_rsn
*ibss_rsn
, const u8
*psk
)
847 if (ibss_rsn
== NULL
)
849 os_memcpy(ibss_rsn
->psk
, psk
, PMK_LEN
);
853 static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn
*ibss_rsn
,
854 struct ibss_rsn_peer
*peer
,
857 wpa_printf(MSG_DEBUG
, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR
,
861 peer
->authentication_status
& (IBSS_RSN_SET_PTK_SUPP
|
862 IBSS_RSN_SET_PTK_AUTH
)) {
863 /* Clear the TK for this pair to allow recovery from the case
864 * where the peer STA has restarted and lost its key while we
865 * still have a pairwise key configured. */
866 wpa_printf(MSG_DEBUG
, "RSN: Clear pairwise key for peer "
867 MACSTR
, MAC2STR(addr
));
868 wpa_drv_set_key(ibss_rsn
->wpa_s
, WPA_ALG_NONE
, addr
, 0, 0,
869 NULL
, 0, NULL
, 0, KEY_FLAG_PAIRWISE
);
873 peer
->authentication_status
& IBSS_RSN_AUTH_EAPOL_BY_PEER
) {
874 if (peer
->own_auth_tx
.sec
) {
875 struct os_reltime now
, diff
;
876 os_get_reltime(&now
);
877 os_reltime_sub(&now
, &peer
->own_auth_tx
, &diff
);
878 if (diff
.sec
== 0 && diff
.usec
< 500000) {
879 wpa_printf(MSG_DEBUG
, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX",
885 * A peer sent us an Authentication frame even though it already
886 * started an EAPOL session. We should reinit state machines
887 * here, but it's much more complicated than just deleting and
888 * recreating the state machine
890 wpa_printf(MSG_DEBUG
, "RSN: IBSS Reinitializing station "
891 MACSTR
, MAC2STR(addr
));
893 ibss_rsn_stop(ibss_rsn
, addr
);
898 peer
= ibss_rsn_peer_init(ibss_rsn
, addr
);
902 wpa_printf(MSG_DEBUG
, "RSN: IBSS Auth started by peer " MACSTR
,
907 /* reply with an Authentication frame now, before sending an EAPOL */
908 ibss_rsn_send_auth(ibss_rsn
, addr
, 2);
909 /* no need to start another AUTH challenge in the other way.. */
910 ibss_rsn_peer_authenticated(ibss_rsn
, peer
, IBSS_RSN_AUTH_EAPOL_BY_US
);
914 void ibss_rsn_handle_auth(struct ibss_rsn
*ibss_rsn
, const u8
*auth_frame
,
917 const struct ieee80211_mgmt
*header
;
918 struct ibss_rsn_peer
*peer
;
921 header
= (const struct ieee80211_mgmt
*) auth_frame
;
922 auth_length
= IEEE80211_HDRLEN
+ sizeof(header
->u
.auth
);
924 if (ibss_rsn
== NULL
|| len
< auth_length
)
927 if (le_to_host16(header
->u
.auth
.auth_alg
) != WLAN_AUTH_OPEN
||
928 le_to_host16(header
->u
.auth
.status_code
) != WLAN_STATUS_SUCCESS
)
931 peer
= ibss_rsn_get_peer(ibss_rsn
, header
->sa
);
933 switch (le_to_host16(header
->u
.auth
.auth_transaction
)) {
935 ibss_rsn_handle_auth_1_of_2(ibss_rsn
, peer
, header
->sa
);
938 wpa_printf(MSG_DEBUG
, "RSN: IBSS RX Auth frame (SEQ 2) from "
939 MACSTR
, MAC2STR(header
->sa
));
941 wpa_printf(MSG_DEBUG
, "RSN: Received Auth seq 2 from "
942 "unknown STA " MACSTR
, MAC2STR(header
->sa
));
946 /* authentication has been completed */
947 eloop_cancel_timeout(ibss_rsn_auth_timeout
, peer
, NULL
);
948 wpa_printf(MSG_DEBUG
, "RSN: IBSS Auth completed with " MACSTR
,
949 MAC2STR(header
->sa
));
950 ibss_rsn_peer_authenticated(ibss_rsn
, peer
,
951 IBSS_RSN_AUTH_BY_US
);