wpa_ie.c
Go to the documentation of this file.
00001 /*
00002  * wpa_supplicant - WPA/RSN IE and KDE processing
00003  * Copyright (c) 2003-2008, 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 "wpa.h"
00019 #include "pmksa_cache.h"
00020 #include "common/ieee802_11_defs.h"
00021 #include "wpa_i.h"
00022 #include "wpa_ie.h"
00023 
00024 
00025 static int wpa_selector_to_bitfield(const u8 *s)
00026 {
00027         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
00028                 return WPA_CIPHER_NONE;
00029         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
00030                 return WPA_CIPHER_WEP40;
00031         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
00032                 return WPA_CIPHER_TKIP;
00033         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
00034                 return WPA_CIPHER_CCMP;
00035         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
00036                 return WPA_CIPHER_WEP104;
00037         return 0;
00038 }
00039 
00040 
00041 static int wpa_key_mgmt_to_bitfield(const u8 *s)
00042 {
00043         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
00044                 return WPA_KEY_MGMT_IEEE8021X;
00045         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
00046                 return WPA_KEY_MGMT_PSK;
00047         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
00048                 return WPA_KEY_MGMT_WPA_NONE;
00049         return 0;
00050 }
00051 
00052 
00053 static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
00054                                 struct wpa_ie_data *data)
00055 {
00056         const struct wpa_ie_hdr *hdr;
00057         const u8 *pos;
00058         int left;
00059         int i, count;
00060 
00061         os_memset(data, 0, sizeof(*data));
00062         data->proto = WPA_PROTO_WPA;
00063         data->pairwise_cipher = WPA_CIPHER_TKIP;
00064         data->group_cipher = WPA_CIPHER_TKIP;
00065         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
00066         data->capabilities = 0;
00067         data->pmkid = NULL;
00068         data->num_pmkid = 0;
00069         data->mgmt_group_cipher = 0;
00070 
00071         if (wpa_ie_len == 0) {
00072                 /* No WPA IE - fail silently */
00073                 return -1;
00074         }
00075 
00076         if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
00077                 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
00078                            __func__, (unsigned long) wpa_ie_len);
00079                 return -1;
00080         }
00081 
00082         hdr = (const struct wpa_ie_hdr *) wpa_ie;
00083 
00084         if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
00085             hdr->len != wpa_ie_len - 2 ||
00086             RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
00087             WPA_GET_LE16(hdr->version) != WPA_VERSION) {
00088                 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
00089                            __func__);
00090                 return -1;
00091         }
00092 
00093         pos = (const u8 *) (hdr + 1);
00094         left = wpa_ie_len - sizeof(*hdr);
00095 
00096         if (left >= WPA_SELECTOR_LEN) {
00097                 data->group_cipher = wpa_selector_to_bitfield(pos);
00098                 pos += WPA_SELECTOR_LEN;
00099                 left -= WPA_SELECTOR_LEN;
00100         } else if (left > 0) {
00101                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
00102                            __func__, left);
00103                 return -1;
00104         }
00105 
00106         if (left >= 2) {
00107                 data->pairwise_cipher = 0;
00108                 count = WPA_GET_LE16(pos);
00109                 pos += 2;
00110                 left -= 2;
00111                 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00112                         wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
00113                                    "count %u left %u", __func__, count, left);
00114                         return -1;
00115                 }
00116                 for (i = 0; i < count; i++) {
00117                         data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
00118                         pos += WPA_SELECTOR_LEN;
00119                         left -= WPA_SELECTOR_LEN;
00120                 }
00121         } else if (left == 1) {
00122                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
00123                            __func__);
00124                 return -1;
00125         }
00126 
00127         if (left >= 2) {
00128                 data->key_mgmt = 0;
00129                 count = WPA_GET_LE16(pos);
00130                 pos += 2;
00131                 left -= 2;
00132                 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00133                         wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
00134                                    "count %u left %u", __func__, count, left);
00135                         return -1;
00136                 }
00137                 for (i = 0; i < count; i++) {
00138                         data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
00139                         pos += WPA_SELECTOR_LEN;
00140                         left -= WPA_SELECTOR_LEN;
00141                 }
00142         } else if (left == 1) {
00143                 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
00144                            __func__);
00145                 return -1;
00146         }
00147 
00148         if (left >= 2) {
00149                 data->capabilities = WPA_GET_LE16(pos);
00150                 pos += 2;
00151                 left -= 2;
00152         }
00153 
00154         if (left > 0) {
00155                 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
00156                            __func__, left);
00157         }
00158 
00159         return 0;
00160 }
00161 
00162 
00172 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
00173                      struct wpa_ie_data *data)
00174 {
00175         if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
00176                 return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
00177         else
00178                 return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
00179 }
00180 
00181 
00182 static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
00183                               int pairwise_cipher, int group_cipher,
00184                               int key_mgmt)
00185 {
00186         u8 *pos;
00187         struct wpa_ie_hdr *hdr;
00188 
00189         if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN +
00190             2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN)
00191                 return -1;
00192 
00193         hdr = (struct wpa_ie_hdr *) wpa_ie;
00194         hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
00195         RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
00196         WPA_PUT_LE16(hdr->version, WPA_VERSION);
00197         pos = (u8 *) (hdr + 1);
00198 
00199         if (group_cipher == WPA_CIPHER_CCMP) {
00200                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00201         } else if (group_cipher == WPA_CIPHER_TKIP) {
00202                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00203         } else if (group_cipher == WPA_CIPHER_WEP104) {
00204                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104);
00205         } else if (group_cipher == WPA_CIPHER_WEP40) {
00206                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40);
00207         } else {
00208                 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00209                            group_cipher);
00210                 return -1;
00211         }
00212         pos += WPA_SELECTOR_LEN;
00213 
00214         *pos++ = 1;
00215         *pos++ = 0;
00216         if (pairwise_cipher == WPA_CIPHER_CCMP) {
00217                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00218         } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00219                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00220         } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00221                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
00222         } else {
00223                 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00224                            pairwise_cipher);
00225                 return -1;
00226         }
00227         pos += WPA_SELECTOR_LEN;
00228 
00229         *pos++ = 1;
00230         *pos++ = 0;
00231         if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00232                 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
00233         } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00234                 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00235         } else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
00236                 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE);
00237         } else {
00238                 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00239                            key_mgmt);
00240                 return -1;
00241         }
00242         pos += WPA_SELECTOR_LEN;
00243 
00244         /* WPA Capabilities; use defaults, so no need to include it */
00245 
00246         hdr->len = (pos - wpa_ie) - 2;
00247 
00248         WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
00249 
00250         return pos - wpa_ie;
00251 }
00252 
00253 
00254 static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
00255                               int pairwise_cipher, int group_cipher,
00256                               int key_mgmt, int mgmt_group_cipher,
00257                               struct wpa_sm *sm)
00258 {
00259 #ifndef CONFIG_NO_WPA2
00260         u8 *pos;
00261         struct rsn_ie_hdr *hdr;
00262         u16 capab;
00263 
00264         if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
00265             2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
00266             (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) {
00267                 wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)",
00268                            (unsigned long) rsn_ie_len);
00269                 return -1;
00270         }
00271 
00272         hdr = (struct rsn_ie_hdr *) rsn_ie;
00273         hdr->elem_id = WLAN_EID_RSN;
00274         WPA_PUT_LE16(hdr->version, RSN_VERSION);
00275         pos = (u8 *) (hdr + 1);
00276 
00277         if (group_cipher == WPA_CIPHER_CCMP) {
00278                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00279         } else if (group_cipher == WPA_CIPHER_TKIP) {
00280                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00281         } else if (group_cipher == WPA_CIPHER_WEP104) {
00282                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104);
00283         } else if (group_cipher == WPA_CIPHER_WEP40) {
00284                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40);
00285         } else {
00286                 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00287                            group_cipher);
00288                 return -1;
00289         }
00290         pos += RSN_SELECTOR_LEN;
00291 
00292         *pos++ = 1;
00293         *pos++ = 0;
00294         if (pairwise_cipher == WPA_CIPHER_CCMP) {
00295                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00296         } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00297                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00298         } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00299                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
00300         } else {
00301                 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00302                            pairwise_cipher);
00303                 return -1;
00304         }
00305         pos += RSN_SELECTOR_LEN;
00306 
00307         *pos++ = 1;
00308         *pos++ = 0;
00309         if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00310                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
00311         } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00312                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00313 #ifdef CONFIG_IEEE80211R
00314         } else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
00315                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
00316         } else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
00317                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
00318 #endif /* CONFIG_IEEE80211R */
00319 #ifdef CONFIG_IEEE80211W
00320         } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
00321                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
00322         } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
00323                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
00324 #endif /* CONFIG_IEEE80211W */
00325         } else {
00326                 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00327                            key_mgmt);
00328                 return -1;
00329         }
00330         pos += RSN_SELECTOR_LEN;
00331 
00332         /* RSN Capabilities */
00333         capab = 0;
00334 #ifdef CONFIG_IEEE80211W
00335         if (sm->mfp)
00336                 capab |= WPA_CAPABILITY_MFPC;
00337         if (sm->mfp == 2)
00338                 capab |= WPA_CAPABILITY_MFPR;
00339 #endif /* CONFIG_IEEE80211W */
00340         WPA_PUT_LE16(pos, capab);
00341         pos += 2;
00342 
00343         if (sm->cur_pmksa) {
00344                 /* PMKID Count (2 octets, little endian) */
00345                 *pos++ = 1;
00346                 *pos++ = 0;
00347                 /* PMKID */
00348                 os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
00349                 pos += PMKID_LEN;
00350         }
00351 
00352 #ifdef CONFIG_IEEE80211W
00353         if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
00354                 if (!sm->cur_pmksa) {
00355                         /* PMKID Count */
00356                         WPA_PUT_LE16(pos, 0);
00357                         pos += 2;
00358                 }
00359 
00360                 /* Management Group Cipher Suite */
00361                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
00362                 pos += RSN_SELECTOR_LEN;
00363         }
00364 #endif /* CONFIG_IEEE80211W */
00365 
00366         hdr->len = (pos - rsn_ie) - 2;
00367 
00368         WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
00369 
00370         return pos - rsn_ie;
00371 #else /* CONFIG_NO_WPA2 */
00372         return -1;
00373 #endif /* CONFIG_NO_WPA2 */
00374 }
00375 
00376 
00384 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
00385 {
00386         if (sm->proto == WPA_PROTO_RSN)
00387                 return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
00388                                           sm->pairwise_cipher,
00389                                           sm->group_cipher,
00390                                           sm->key_mgmt, sm->mgmt_group_cipher,
00391                                           sm);
00392         else
00393                 return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
00394                                           sm->pairwise_cipher,
00395                                           sm->group_cipher,
00396                                           sm->key_mgmt);
00397 }
00398 
00399 
00407 static int wpa_parse_generic(const u8 *pos, const u8 *end,
00408                              struct wpa_eapol_ie_parse *ie)
00409 {
00410         if (pos[1] == 0)
00411                 return 1;
00412 
00413         if (pos[1] >= 6 &&
00414             RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
00415             pos[2 + WPA_SELECTOR_LEN] == 1 &&
00416             pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
00417                 ie->wpa_ie = pos;
00418                 ie->wpa_ie_len = pos[1] + 2;
00419                 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
00420                             ie->wpa_ie, ie->wpa_ie_len);
00421                 return 0;
00422         }
00423 
00424         if (pos + 1 + RSN_SELECTOR_LEN < end &&
00425             pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
00426             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
00427                 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
00428                 wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
00429                             pos, pos[1] + 2);
00430                 return 0;
00431         }
00432 
00433         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00434             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
00435                 ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
00436                 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
00437                 wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key",
00438                                 pos, pos[1] + 2);
00439                 return 0;
00440         }
00441 
00442         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00443             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
00444                 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
00445                 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
00446                 wpa_hexdump(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key",
00447                             pos, pos[1] + 2);
00448                 return 0;
00449         }
00450 
00451 #ifdef CONFIG_PEERKEY
00452         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00453             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
00454                 ie->smk = pos + 2 + RSN_SELECTOR_LEN;
00455                 ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
00456                 wpa_hexdump_key(MSG_DEBUG, "WPA: SMK in EAPOL-Key",
00457                                 pos, pos[1] + 2);
00458                 return 0;
00459         }
00460 
00461         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00462             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
00463                 ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
00464                 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
00465                 wpa_hexdump(MSG_DEBUG, "WPA: Nonce in EAPOL-Key",
00466                             pos, pos[1] + 2);
00467                 return 0;
00468         }
00469 
00470         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00471             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
00472                 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
00473                 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
00474                 wpa_hexdump(MSG_DEBUG, "WPA: Lifetime in EAPOL-Key",
00475                             pos, pos[1] + 2);
00476                 return 0;
00477         }
00478 
00479         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00480             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
00481                 ie->error = pos + 2 + RSN_SELECTOR_LEN;
00482                 ie->error_len = pos[1] - RSN_SELECTOR_LEN;
00483                 wpa_hexdump(MSG_DEBUG, "WPA: Error in EAPOL-Key",
00484                             pos, pos[1] + 2);
00485                 return 0;
00486         }
00487 #endif /* CONFIG_PEERKEY */
00488 
00489 #ifdef CONFIG_IEEE80211W
00490         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00491             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
00492                 ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
00493                 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
00494                 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
00495                                 pos, pos[1] + 2);
00496                 return 0;
00497         }
00498 #endif /* CONFIG_IEEE80211W */
00499 
00500         return 0;
00501 }
00502 
00503 
00511 int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
00512                              struct wpa_eapol_ie_parse *ie)
00513 {
00514         const u8 *pos, *end;
00515         int ret = 0;
00516 
00517         os_memset(ie, 0, sizeof(*ie));
00518         for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
00519                 if (pos[0] == 0xdd &&
00520                     ((pos == buf + len - 1) || pos[1] == 0)) {
00521                         /* Ignore padding */
00522                         break;
00523                 }
00524                 if (pos + 2 + pos[1] > end) {
00525                         wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
00526                                    "underflow (ie=%d len=%d pos=%d)",
00527                                    pos[0], pos[1], (int) (pos - buf));
00528                         wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
00529                                         buf, len);
00530                         ret = -1;
00531                         break;
00532                 }
00533                 if (*pos == WLAN_EID_RSN) {
00534                         ie->rsn_ie = pos;
00535                         ie->rsn_ie_len = pos[1] + 2;
00536                         wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
00537                                     ie->rsn_ie, ie->rsn_ie_len);
00538 #ifdef CONFIG_IEEE80211R
00539                 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
00540                         ie->mdie = pos;
00541                         ie->mdie_len = pos[1] + 2;
00542                         wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
00543                                     ie->mdie, ie->mdie_len);
00544                 } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
00545                         ie->ftie = pos;
00546                         ie->ftie_len = pos[1] + 2;
00547                         wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
00548                                     ie->ftie, ie->ftie_len);
00549                 } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
00550                         if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
00551                                 ie->reassoc_deadline = pos;
00552                                 wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
00553                                             "in EAPOL-Key",
00554                                             ie->reassoc_deadline, pos[1] + 2);
00555                         } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
00556                                 ie->key_lifetime = pos;
00557                                 wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
00558                                             "in EAPOL-Key",
00559                                             ie->key_lifetime, pos[1] + 2);
00560                         } else {
00561                                 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
00562                                             "EAPOL-Key Key Data IE",
00563                                             pos, 2 + pos[1]);
00564                         }
00565 #endif /* CONFIG_IEEE80211R */
00566                 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
00567                         ret = wpa_parse_generic(pos, end, ie);
00568                         if (ret < 0)
00569                                 break;
00570                         if (ret > 0) {
00571                                 ret = 0;
00572                                 break;
00573                         }
00574                 } else {
00575                         wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
00576                                     "Key Data IE", pos, 2 + pos[1]);
00577                 }
00578         }
00579 
00580         return ret;
00581 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36