$search
00001 /* 00002 * wpa_supplicant - IBSS RSN 00003 * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "l2_packet/l2_packet.h" 00019 #include "rsn_supp/wpa.h" 00020 #include "rsn_supp/wpa_ie.h" 00021 #include "ap/wpa_auth.h" 00022 #include "wpa_supplicant_i.h" 00023 #include "driver_i.h" 00024 #include "ibss_rsn.h" 00025 00026 00027 static void ibss_rsn_free(struct ibss_rsn_peer *peer) 00028 { 00029 wpa_auth_sta_deinit(peer->auth); 00030 wpa_sm_deinit(peer->supp); 00031 os_free(peer); 00032 } 00033 00034 00035 static void supp_set_state(void *ctx, enum wpa_states state) 00036 { 00037 struct ibss_rsn_peer *peer = ctx; 00038 peer->supp_state = state; 00039 } 00040 00041 00042 static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf, 00043 size_t len) 00044 { 00045 struct ibss_rsn_peer *peer = ctx; 00046 struct wpa_supplicant *wpa_s = peer->ibss_rsn->wpa_s; 00047 00048 wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x " 00049 "len=%lu)", 00050 __func__, MAC2STR(dest), proto, (unsigned long) len); 00051 00052 if (wpa_s->l2) 00053 return l2_packet_send(wpa_s->l2, dest, proto, buf, len); 00054 00055 return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len); 00056 } 00057 00058 00059 static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data, 00060 u16 data_len, size_t *msg_len, void **data_pos) 00061 { 00062 struct ieee802_1x_hdr *hdr; 00063 00064 wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)", 00065 __func__, type, data_len); 00066 00067 *msg_len = sizeof(*hdr) + data_len; 00068 hdr = os_malloc(*msg_len); 00069 if (hdr == NULL) 00070 return NULL; 00071 00072 hdr->version = 2; 00073 hdr->type = type; 00074 hdr->length = host_to_be16(data_len); 00075 00076 if (data) 00077 os_memcpy(hdr + 1, data, data_len); 00078 else 00079 os_memset(hdr + 1, 0, data_len); 00080 00081 if (data_pos) 00082 *data_pos = hdr + 1; 00083 00084 return (u8 *) hdr; 00085 } 00086 00087 00088 static int supp_get_beacon_ie(void *ctx) 00089 { 00090 struct ibss_rsn_peer *peer = ctx; 00091 00092 wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); 00093 /* TODO: get correct RSN IE */ 00094 return wpa_sm_set_ap_rsn_ie(peer->supp, 00095 (u8 *) "\x30\x14\x01\x00" 00096 "\x00\x0f\xac\x04" 00097 "\x01\x00\x00\x0f\xac\x04" 00098 "\x01\x00\x00\x0f\xac\x02" 00099 "\x00\x00", 22); 00100 } 00101 00102 00103 static int supp_set_key(void *ctx, enum wpa_alg alg, 00104 const u8 *addr, int key_idx, int set_tx, 00105 const u8 *seq, size_t seq_len, 00106 const u8 *key, size_t key_len) 00107 { 00108 struct ibss_rsn_peer *peer = ctx; 00109 00110 wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d " 00111 "set_tx=%d)", 00112 __func__, alg, MAC2STR(addr), key_idx, set_tx); 00113 wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len); 00114 wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len); 00115 00116 if (key_idx == 0) { 00117 /* 00118 * In IBSS RSN, the pairwise key from the 4-way handshake 00119 * initiated by the peer with highest MAC address is used. 00120 */ 00121 if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr, 00122 ETH_ALEN) > 0) { 00123 wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK"); 00124 return 0; 00125 } 00126 } 00127 00128 return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx, 00129 set_tx, seq, seq_len, key, key_len); 00130 } 00131 00132 00133 static void * supp_get_network_ctx(void *ctx) 00134 { 00135 struct ibss_rsn_peer *peer = ctx; 00136 return wpa_supplicant_get_ssid(peer->ibss_rsn->wpa_s); 00137 } 00138 00139 00140 static int supp_mlme_setprotection(void *ctx, const u8 *addr, 00141 int protection_type, int key_type) 00142 { 00143 wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d " 00144 "key_type=%d)", 00145 __func__, MAC2STR(addr), protection_type, key_type); 00146 return 0; 00147 } 00148 00149 00150 static void supp_cancel_auth_timeout(void *ctx) 00151 { 00152 wpa_printf(MSG_DEBUG, "SUPP: %s", __func__); 00153 } 00154 00155 00156 int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr, 00157 const u8 *psk) 00158 { 00159 struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx)); 00160 if (ctx == NULL) 00161 return -1; 00162 00163 ctx->ctx = peer; 00164 ctx->msg_ctx = peer->ibss_rsn->wpa_s; 00165 ctx->set_state = supp_set_state; 00166 ctx->ether_send = supp_ether_send; 00167 ctx->get_beacon_ie = supp_get_beacon_ie; 00168 ctx->alloc_eapol = supp_alloc_eapol; 00169 ctx->set_key = supp_set_key; 00170 ctx->get_network_ctx = supp_get_network_ctx; 00171 ctx->mlme_setprotection = supp_mlme_setprotection; 00172 ctx->cancel_auth_timeout = supp_cancel_auth_timeout; 00173 peer->supp = wpa_sm_init(ctx); 00174 if (peer->supp == NULL) { 00175 wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed"); 00176 return -1; 00177 } 00178 00179 wpa_sm_set_own_addr(peer->supp, own_addr); 00180 wpa_sm_set_param(peer->supp, WPA_PARAM_RSN_ENABLED, 1); 00181 wpa_sm_set_param(peer->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN); 00182 wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP); 00183 wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP); 00184 wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK); 00185 wpa_sm_set_pmk(peer->supp, psk, PMK_LEN); 00186 00187 peer->supp_ie_len = sizeof(peer->supp_ie); 00188 if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie, 00189 &peer->supp_ie_len) < 0) { 00190 wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()" 00191 " failed"); 00192 return -1; 00193 } 00194 00195 wpa_sm_notify_assoc(peer->supp, peer->addr); 00196 00197 return 0; 00198 } 00199 00200 00201 static void auth_logger(void *ctx, const u8 *addr, logger_level level, 00202 const char *txt) 00203 { 00204 if (addr) 00205 wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s", 00206 MAC2STR(addr), txt); 00207 else 00208 wpa_printf(MSG_DEBUG, "AUTH: %s", txt); 00209 } 00210 00211 00212 static const u8 * auth_get_psk(void *ctx, const u8 *addr, const u8 *prev_psk) 00213 { 00214 struct ibss_rsn *ibss_rsn = ctx; 00215 wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)", 00216 __func__, MAC2STR(addr), prev_psk); 00217 if (prev_psk) 00218 return NULL; 00219 return ibss_rsn->psk; 00220 } 00221 00222 00223 static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data, 00224 size_t data_len, int encrypt) 00225 { 00226 struct ibss_rsn *ibss_rsn = ctx; 00227 struct wpa_supplicant *wpa_s = ibss_rsn->wpa_s; 00228 00229 wpa_printf(MSG_DEBUG, "AUTH: %s(addr=" MACSTR " data_len=%lu " 00230 "encrypt=%d)", 00231 __func__, MAC2STR(addr), (unsigned long) data_len, encrypt); 00232 00233 if (wpa_s->l2) 00234 return l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, 00235 data_len); 00236 00237 return wpa_drv_send_eapol(wpa_s, addr, ETH_P_EAPOL, data, data_len); 00238 } 00239 00240 00241 static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, 00242 const u8 *addr, int idx, u8 *key, size_t key_len) 00243 { 00244 struct ibss_rsn *ibss_rsn = ctx; 00245 u8 seq[6]; 00246 00247 os_memset(seq, 0, sizeof(seq)); 00248 00249 if (addr) { 00250 wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR 00251 " key_idx=%d)", 00252 __func__, alg, MAC2STR(addr), idx); 00253 } else { 00254 wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)", 00255 __func__, alg, idx); 00256 } 00257 wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len); 00258 00259 if (idx == 0) { 00260 /* 00261 * In IBSS RSN, the pairwise key from the 4-way handshake 00262 * initiated by the peer with highest MAC address is used. 00263 */ 00264 if (addr == NULL || 00265 os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) { 00266 wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK"); 00267 return 0; 00268 } 00269 } 00270 00271 return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx, 00272 1, seq, 6, key, key_len); 00273 } 00274 00275 00276 static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn, 00277 const u8 *own_addr) 00278 { 00279 struct wpa_auth_config conf; 00280 struct wpa_auth_callbacks cb; 00281 00282 wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); 00283 00284 os_memset(&conf, 0, sizeof(conf)); 00285 conf.wpa = 2; 00286 conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK; 00287 conf.wpa_pairwise = WPA_CIPHER_CCMP; 00288 conf.rsn_pairwise = WPA_CIPHER_CCMP; 00289 conf.wpa_group = WPA_CIPHER_CCMP; 00290 conf.eapol_version = 2; 00291 00292 os_memset(&cb, 0, sizeof(cb)); 00293 cb.ctx = ibss_rsn; 00294 cb.logger = auth_logger; 00295 cb.send_eapol = auth_send_eapol; 00296 cb.get_psk = auth_get_psk; 00297 cb.set_key = auth_set_key; 00298 00299 ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb); 00300 if (ibss_rsn->auth_group == NULL) { 00301 wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); 00302 return -1; 00303 } 00304 00305 return 0; 00306 } 00307 00308 00309 static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn, 00310 struct ibss_rsn_peer *peer) 00311 { 00312 peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr); 00313 if (peer->auth == NULL) { 00314 wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed"); 00315 return -1; 00316 } 00317 00318 /* TODO: get peer RSN IE with Probe Request */ 00319 if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, 00320 (u8 *) "\x30\x14\x01\x00" 00321 "\x00\x0f\xac\x04" 00322 "\x01\x00\x00\x0f\xac\x04" 00323 "\x01\x00\x00\x0f\xac\x02" 00324 "\x00\x00", 22, NULL, 0) != 00325 WPA_IE_OK) { 00326 wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed"); 00327 return -1; 00328 } 00329 00330 if (wpa_auth_sm_event(peer->auth, WPA_ASSOC)) 00331 return -1; 00332 00333 if (wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth)) 00334 return -1; 00335 00336 return 0; 00337 } 00338 00339 00340 int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr) 00341 { 00342 struct ibss_rsn_peer *peer; 00343 00344 wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Authenticator and " 00345 "Supplicant for peer " MACSTR, MAC2STR(addr)); 00346 00347 peer = os_zalloc(sizeof(*peer)); 00348 if (peer == NULL) 00349 return -1; 00350 00351 peer->ibss_rsn = ibss_rsn; 00352 os_memcpy(peer->addr, addr, ETH_ALEN); 00353 00354 if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr, ibss_rsn->psk) 00355 < 0) { 00356 ibss_rsn_free(peer); 00357 return -1; 00358 } 00359 00360 if (ibss_rsn_auth_init(ibss_rsn, peer) < 0) { 00361 ibss_rsn_free(peer); 00362 return -1; 00363 } 00364 00365 peer->next = ibss_rsn->peers; 00366 ibss_rsn->peers = peer; 00367 00368 return 0; 00369 } 00370 00371 00372 struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s) 00373 { 00374 struct ibss_rsn *ibss_rsn; 00375 00376 ibss_rsn = os_zalloc(sizeof(*ibss_rsn)); 00377 if (ibss_rsn == NULL) 00378 return NULL; 00379 ibss_rsn->wpa_s = wpa_s; 00380 00381 if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr) < 0) { 00382 ibss_rsn_deinit(ibss_rsn); 00383 return NULL; 00384 } 00385 00386 return ibss_rsn; 00387 } 00388 00389 00390 void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn) 00391 { 00392 struct ibss_rsn_peer *peer, *prev; 00393 00394 if (ibss_rsn == NULL) 00395 return; 00396 00397 peer = ibss_rsn->peers; 00398 while (peer) { 00399 prev = peer; 00400 peer = peer->next; 00401 ibss_rsn_free(prev); 00402 } 00403 00404 wpa_deinit(ibss_rsn->auth_group); 00405 os_free(ibss_rsn); 00406 00407 } 00408 00409 00410 static int ibss_rsn_eapol_dst_supp(const u8 *buf, size_t len) 00411 { 00412 const struct ieee802_1x_hdr *hdr; 00413 const struct wpa_eapol_key *key; 00414 u16 key_info; 00415 size_t plen; 00416 00417 /* TODO: Support other EAPOL packets than just EAPOL-Key */ 00418 00419 if (len < sizeof(*hdr) + sizeof(*key)) 00420 return -1; 00421 00422 hdr = (const struct ieee802_1x_hdr *) buf; 00423 key = (const struct wpa_eapol_key *) (hdr + 1); 00424 plen = be_to_host16(hdr->length); 00425 00426 if (hdr->version < EAPOL_VERSION) { 00427 /* TODO: backwards compatibility */ 00428 } 00429 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) { 00430 wpa_printf(MSG_DEBUG, "RSN: EAPOL frame (type %u) discarded, " 00431 "not a Key frame", hdr->type); 00432 return -1; 00433 } 00434 if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) { 00435 wpa_printf(MSG_DEBUG, "RSN: EAPOL frame payload size %lu " 00436 "invalid (frame size %lu)", 00437 (unsigned long) plen, (unsigned long) len); 00438 return -1; 00439 } 00440 00441 if (key->type != EAPOL_KEY_TYPE_RSN) { 00442 wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key type (%d) unknown, " 00443 "discarded", key->type); 00444 return -1; 00445 } 00446 00447 key_info = WPA_GET_BE16(key->key_info); 00448 00449 return !!(key_info & WPA_KEY_INFO_ACK); 00450 } 00451 00452 00453 static int ibss_rsn_process_rx_eapol(struct ibss_rsn *ibss_rsn, 00454 struct ibss_rsn_peer *peer, 00455 const u8 *buf, size_t len) 00456 { 00457 int supp; 00458 u8 *tmp; 00459 00460 supp = ibss_rsn_eapol_dst_supp(buf, len); 00461 if (supp < 0) 00462 return -1; 00463 00464 tmp = os_malloc(len); 00465 if (tmp == NULL) 00466 return -1; 00467 os_memcpy(tmp, buf, len); 00468 if (supp) { 00469 wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Supplicant"); 00470 wpa_sm_rx_eapol(peer->supp, peer->addr, tmp, len); 00471 } else { 00472 wpa_printf(MSG_DEBUG, "RSN: IBSS RX EAPOL for Authenticator"); 00473 wpa_receive(ibss_rsn->auth_group, peer->auth, tmp, len); 00474 } 00475 os_free(tmp); 00476 00477 return 1; 00478 } 00479 00480 00481 int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr, 00482 const u8 *buf, size_t len) 00483 { 00484 struct ibss_rsn_peer *peer; 00485 00486 for (peer = ibss_rsn->peers; peer; peer = peer->next) { 00487 if (os_memcmp(src_addr, peer->addr, ETH_ALEN) == 0) 00488 return ibss_rsn_process_rx_eapol(ibss_rsn, peer, 00489 buf, len); 00490 } 00491 00492 if (ibss_rsn_eapol_dst_supp(buf, len) > 0) { 00493 /* 00494 * Create new IBSS peer based on an EAPOL message from the peer 00495 * Authenticator. 00496 */ 00497 if (ibss_rsn_start(ibss_rsn, src_addr) < 0) 00498 return -1; 00499 return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers, 00500 buf, len); 00501 } 00502 00503 return 0; 00504 } 00505 00506 00507 void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk) 00508 { 00509 os_memcpy(ibss_rsn->psk, psk, PMK_LEN); 00510 }