]>
git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/ibss_rsn.c
2 * wpa_supplicant - IBSS RSN
3 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "l2_packet/l2_packet.h"
19 #include "wpa_supplicant_i.h"
22 #include "../hostapd/wpa.h"
26 static void ibss_rsn_free(struct ibss_rsn_peer
*peer
)
28 wpa_auth_sta_deinit(peer
->auth
);
29 wpa_sm_deinit(peer
->supp
);
34 static int supp_ether_send(void *ctx
, const u8
*dest
, u16 proto
, const u8
*buf
,
37 struct ibss_rsn_peer
*peer
= ctx
;
38 struct wpa_supplicant
*wpa_s
= peer
->ibss_rsn
->wpa_s
;
40 wpa_printf(MSG_DEBUG
, "SUPP: %s(dest=" MACSTR
" proto=0x%04x "
42 __func__
, MAC2STR(dest
), proto
, (unsigned long) len
);
45 return l2_packet_send(wpa_s
->l2
, dest
, proto
, buf
, len
);
47 return wpa_drv_send_eapol(wpa_s
, dest
, proto
, buf
, len
);
51 static u8
* supp_alloc_eapol(void *ctx
, u8 type
, const void *data
,
52 u16 data_len
, size_t *msg_len
, void **data_pos
)
54 struct ieee802_1x_hdr
*hdr
;
56 wpa_printf(MSG_DEBUG
, "SUPP: %s(type=%d data_len=%d)",
57 __func__
, type
, data_len
);
59 *msg_len
= sizeof(*hdr
) + data_len
;
60 hdr
= os_malloc(*msg_len
);
66 hdr
->length
= host_to_be16(data_len
);
69 os_memcpy(hdr
+ 1, data
, data_len
);
71 os_memset(hdr
+ 1, 0, data_len
);
80 static int supp_get_beacon_ie(void *ctx
)
82 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
88 static int supp_set_key(void *ctx
, wpa_alg alg
,
89 const u8
*addr
, int key_idx
, int set_tx
,
90 const u8
*seq
, size_t seq_len
,
91 const u8
*key
, size_t key_len
)
93 wpa_printf(MSG_DEBUG
, "SUPP: %s(alg=%d addr=" MACSTR
" key_idx=%d "
95 __func__
, alg
, MAC2STR(addr
), key_idx
, set_tx
);
96 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - seq", seq
, seq_len
);
97 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - key", key
, key_len
);
102 static int supp_mlme_setprotection(void *ctx
, const u8
*addr
,
103 int protection_type
, int key_type
)
105 wpa_printf(MSG_DEBUG
, "SUPP: %s(addr=" MACSTR
" protection_type=%d "
107 __func__
, MAC2STR(addr
), protection_type
, key_type
);
112 static void supp_cancel_auth_timeout(void *ctx
)
114 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
118 int ibss_rsn_supp_init(struct ibss_rsn_peer
*peer
, const u8
*own_addr
,
121 struct wpa_sm_ctx
*ctx
= os_zalloc(sizeof(*ctx
));
126 ctx
->ether_send
= supp_ether_send
;
127 ctx
->get_beacon_ie
= supp_get_beacon_ie
;
128 ctx
->alloc_eapol
= supp_alloc_eapol
;
129 ctx
->set_key
= supp_set_key
;
130 ctx
->mlme_setprotection
= supp_mlme_setprotection
;
131 ctx
->cancel_auth_timeout
= supp_cancel_auth_timeout
;
132 peer
->supp
= wpa_sm_init(ctx
);
133 if (peer
->supp
== NULL
) {
134 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_init() failed");
138 wpa_sm_set_own_addr(peer
->supp
, own_addr
);
139 wpa_sm_set_param(peer
->supp
, WPA_PARAM_RSN_ENABLED
, 1);
140 wpa_sm_set_param(peer
->supp
, WPA_PARAM_PROTO
, WPA_PROTO_RSN
);
141 wpa_sm_set_param(peer
->supp
, WPA_PARAM_PAIRWISE
, WPA_CIPHER_CCMP
);
142 wpa_sm_set_param(peer
->supp
, WPA_PARAM_GROUP
, WPA_CIPHER_CCMP
);
143 wpa_sm_set_param(peer
->supp
, WPA_PARAM_KEY_MGMT
, WPA_KEY_MGMT_PSK
);
144 wpa_sm_set_pmk(peer
->supp
, psk
, PMK_LEN
);
147 peer
->supp_ie_len
= sizeof(peer
->supp_ie
);
148 if (wpa_sm_set_assoc_wpa_ie_default(peer
->supp
, peer
->supp_ie
,
149 &peer
->supp_ie_len
) < 0) {
150 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
156 wpa_sm_notify_assoc(peer
->supp
, peer
->addr
);
162 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
166 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
169 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
173 static const u8
* auth_get_psk(void *ctx
, const u8
*addr
, const u8
*prev_psk
)
175 struct ibss_rsn
*ibss_rsn
= ctx
;
176 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
177 __func__
, MAC2STR(addr
), prev_psk
);
180 return ibss_rsn
->psk
;
184 static int auth_send_eapol(void *ctx
, const u8
*addr
, const u8
*data
,
185 size_t data_len
, int encrypt
)
187 struct ibss_rsn
*ibss_rsn
= ctx
;
188 struct wpa_supplicant
*wpa_s
= ibss_rsn
->wpa_s
;
190 wpa_printf(MSG_DEBUG
, "AUTH: %s(addr=" MACSTR
" data_len=%lu "
192 __func__
, MAC2STR(addr
), (unsigned long) data_len
, encrypt
);
195 return l2_packet_send(wpa_s
->l2
, addr
, ETH_P_EAPOL
, data
,
198 return wpa_drv_send_eapol(wpa_s
, addr
, ETH_P_EAPOL
, data
, data_len
);
202 static int ibss_rsn_auth_init_group(struct ibss_rsn
*ibss_rsn
,
205 struct wpa_auth_config conf
;
206 struct wpa_auth_callbacks cb
;
208 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
210 os_memset(&conf
, 0, sizeof(conf
));
212 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
213 conf
.wpa_pairwise
= WPA_CIPHER_CCMP
;
214 conf
.rsn_pairwise
= WPA_CIPHER_CCMP
;
215 conf
.wpa_group
= WPA_CIPHER_CCMP
;
216 conf
.eapol_version
= 2;
218 os_memset(&cb
, 0, sizeof(cb
));
220 cb
.logger
= auth_logger
;
221 cb
.send_eapol
= auth_send_eapol
;
222 cb
.get_psk
= auth_get_psk
;
224 ibss_rsn
->auth_group
= wpa_init(own_addr
, &conf
, &cb
);
225 if (ibss_rsn
->auth_group
== NULL
) {
226 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
234 static int ibss_rsn_auth_init(struct ibss_rsn
*ibss_rsn
,
235 struct ibss_rsn_peer
*peer
)
237 peer
->auth
= wpa_auth_sta_init(ibss_rsn
->auth_group
, peer
->addr
);
238 if (peer
->auth
== NULL
) {
239 wpa_printf(MSG_DEBUG
, "AUTH: wpa_auth_sta_init() failed");
243 /* TODO: get peer RSN IE with Probe Request */
244 if (wpa_validate_wpa_ie(ibss_rsn
->auth_group
, peer
->auth
,
245 (u8
*) "\x30\x12\x01\x00"
247 "\x01\x00\x00\x0f\xac\x04"
248 "\x01\x00\x00\x0f\xac\x02", 20, NULL
, 0) !=
250 wpa_printf(MSG_DEBUG
, "AUTH: wpa_validate_wpa_ie() failed");
254 wpa_auth_sm_event(peer
->auth
, WPA_ASSOC
);
256 wpa_auth_sta_associated(ibss_rsn
->auth_group
, peer
->auth
);
262 int ibss_rsn_start(struct ibss_rsn
*ibss_rsn
, const u8
*addr
)
264 struct ibss_rsn_peer
*peer
;
266 wpa_printf(MSG_DEBUG
, "RSN: Starting IBSS Authenticator and "
267 "Supplicant for peer " MACSTR
, MAC2STR(addr
));
269 peer
= os_zalloc(sizeof(*peer
));
273 peer
->ibss_rsn
= ibss_rsn
;
274 os_memcpy(peer
->addr
, addr
, ETH_ALEN
);
276 if (ibss_rsn_supp_init(peer
, ibss_rsn
->wpa_s
->own_addr
, ibss_rsn
->psk
)
282 if (ibss_rsn_auth_init(ibss_rsn
, peer
) < 0) {
287 peer
->next
= ibss_rsn
->peers
;
288 ibss_rsn
->peers
= peer
;
294 struct ibss_rsn
* ibss_rsn_init(struct wpa_supplicant
*wpa_s
)
296 struct ibss_rsn
*ibss_rsn
;
298 ibss_rsn
= os_zalloc(sizeof(*ibss_rsn
));
299 if (ibss_rsn
== NULL
)
301 ibss_rsn
->wpa_s
= wpa_s
;
303 if (ibss_rsn_auth_init_group(ibss_rsn
, wpa_s
->own_addr
) < 0) {
304 ibss_rsn_deinit(ibss_rsn
);
312 void ibss_rsn_deinit(struct ibss_rsn
*ibss_rsn
)
314 struct ibss_rsn_peer
*peer
, *prev
;
316 if (ibss_rsn
== NULL
)
319 peer
= ibss_rsn
->peers
;
326 wpa_deinit(ibss_rsn
->auth_group
);