LCOV - code coverage report
Current view: top level - src/ap - wpa_auth_ie.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 383 480 79.8 %
Date: 2014-05-28 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd - WPA/RSN IE and KDE definitions
       3             :  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #include "utils/common.h"
      12             : #include "common/ieee802_11_defs.h"
      13             : #include "eapol_auth/eapol_auth_sm.h"
      14             : #include "ap_config.h"
      15             : #include "ieee802_11.h"
      16             : #include "wpa_auth.h"
      17             : #include "pmksa_cache_auth.h"
      18             : #include "wpa_auth_ie.h"
      19             : #include "wpa_auth_i.h"
      20             : 
      21             : 
      22             : #ifdef CONFIG_RSN_TESTING
      23             : int rsn_testing = 0;
      24             : #endif /* CONFIG_RSN_TESTING */
      25             : 
      26             : 
      27          23 : static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
      28             : {
      29             :         struct wpa_ie_hdr *hdr;
      30             :         int num_suites;
      31             :         u8 *pos, *count;
      32             :         u32 suite;
      33             : 
      34          23 :         hdr = (struct wpa_ie_hdr *) buf;
      35          23 :         hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
      36          23 :         RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
      37          23 :         WPA_PUT_LE16(hdr->version, WPA_VERSION);
      38          23 :         pos = (u8 *) (hdr + 1);
      39             : 
      40          23 :         suite = wpa_cipher_to_suite(WPA_PROTO_WPA, conf->wpa_group);
      41          23 :         if (suite == 0) {
      42           0 :                 wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
      43             :                            conf->wpa_group);
      44           0 :                 return -1;
      45             :         }
      46          23 :         RSN_SELECTOR_PUT(pos, suite);
      47          23 :         pos += WPA_SELECTOR_LEN;
      48             : 
      49          23 :         count = pos;
      50          23 :         pos += 2;
      51             : 
      52          23 :         num_suites = wpa_cipher_put_suites(pos, conf->wpa_pairwise);
      53          23 :         if (num_suites == 0) {
      54           0 :                 wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
      55             :                            conf->wpa_pairwise);
      56           0 :                 return -1;
      57             :         }
      58          23 :         pos += num_suites * WPA_SELECTOR_LEN;
      59          23 :         WPA_PUT_LE16(count, num_suites);
      60             : 
      61          23 :         num_suites = 0;
      62          23 :         count = pos;
      63          23 :         pos += 2;
      64             : 
      65          23 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
      66           2 :                 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
      67           2 :                 pos += WPA_SELECTOR_LEN;
      68           2 :                 num_suites++;
      69             :         }
      70          23 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
      71          22 :                 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
      72          22 :                 pos += WPA_SELECTOR_LEN;
      73          22 :                 num_suites++;
      74             :         }
      75             : 
      76          23 :         if (num_suites == 0) {
      77           0 :                 wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
      78             :                            conf->wpa_key_mgmt);
      79           0 :                 return -1;
      80             :         }
      81          23 :         WPA_PUT_LE16(count, num_suites);
      82             : 
      83             :         /* WPA Capabilities; use defaults, so no need to include it */
      84             : 
      85          23 :         hdr->len = (pos - buf) - 2;
      86             : 
      87          23 :         return pos - buf;
      88             : }
      89             : 
      90             : 
      91         542 : int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
      92             :                      const u8 *pmkid)
      93             : {
      94             :         struct rsn_ie_hdr *hdr;
      95             :         int num_suites, res;
      96             :         u8 *pos, *count;
      97             :         u16 capab;
      98             :         u32 suite;
      99             : 
     100         542 :         hdr = (struct rsn_ie_hdr *) buf;
     101         542 :         hdr->elem_id = WLAN_EID_RSN;
     102         542 :         WPA_PUT_LE16(hdr->version, RSN_VERSION);
     103         542 :         pos = (u8 *) (hdr + 1);
     104             : 
     105         542 :         suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group);
     106         542 :         if (suite == 0) {
     107           0 :                 wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
     108             :                            conf->wpa_group);
     109           0 :                 return -1;
     110             :         }
     111         542 :         RSN_SELECTOR_PUT(pos, suite);
     112         542 :         pos += RSN_SELECTOR_LEN;
     113             : 
     114         542 :         num_suites = 0;
     115         542 :         count = pos;
     116         542 :         pos += 2;
     117             : 
     118             : #ifdef CONFIG_RSN_TESTING
     119             :         if (rsn_testing) {
     120             :                 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
     121             :                 pos += RSN_SELECTOR_LEN;
     122             :                 num_suites++;
     123             :         }
     124             : #endif /* CONFIG_RSN_TESTING */
     125             : 
     126         542 :         res = rsn_cipher_put_suites(pos, conf->rsn_pairwise);
     127         542 :         num_suites += res;
     128         542 :         pos += res * RSN_SELECTOR_LEN;
     129             : 
     130             : #ifdef CONFIG_RSN_TESTING
     131             :         if (rsn_testing) {
     132             :                 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
     133             :                 pos += RSN_SELECTOR_LEN;
     134             :                 num_suites++;
     135             :         }
     136             : #endif /* CONFIG_RSN_TESTING */
     137             : 
     138         542 :         if (num_suites == 0) {
     139           0 :                 wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
     140             :                            conf->rsn_pairwise);
     141           0 :                 return -1;
     142             :         }
     143         542 :         WPA_PUT_LE16(count, num_suites);
     144             : 
     145         542 :         num_suites = 0;
     146         542 :         count = pos;
     147         542 :         pos += 2;
     148             : 
     149             : #ifdef CONFIG_RSN_TESTING
     150             :         if (rsn_testing) {
     151             :                 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
     152             :                 pos += RSN_SELECTOR_LEN;
     153             :                 num_suites++;
     154             :         }
     155             : #endif /* CONFIG_RSN_TESTING */
     156             : 
     157         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
     158         208 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
     159         208 :                 pos += RSN_SELECTOR_LEN;
     160         208 :                 num_suites++;
     161             :         }
     162         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
     163         258 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
     164         258 :                 pos += RSN_SELECTOR_LEN;
     165         258 :                 num_suites++;
     166             :         }
     167             : #ifdef CONFIG_IEEE80211R
     168         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
     169          13 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
     170          13 :                 pos += RSN_SELECTOR_LEN;
     171          13 :                 num_suites++;
     172             :         }
     173         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
     174          46 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
     175          46 :                 pos += RSN_SELECTOR_LEN;
     176          46 :                 num_suites++;
     177             :         }
     178             : #endif /* CONFIG_IEEE80211R */
     179             : #ifdef CONFIG_IEEE80211W
     180         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
     181           2 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
     182           2 :                 pos += RSN_SELECTOR_LEN;
     183           2 :                 num_suites++;
     184             :         }
     185         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
     186           7 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
     187           7 :                 pos += RSN_SELECTOR_LEN;
     188           7 :                 num_suites++;
     189             :         }
     190             : #endif /* CONFIG_IEEE80211W */
     191             : #ifdef CONFIG_SAE
     192         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
     193           6 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
     194           6 :                 pos += RSN_SELECTOR_LEN;
     195           6 :                 num_suites++;
     196             :         }
     197         542 :         if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
     198          12 :                 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
     199          12 :                 pos += RSN_SELECTOR_LEN;
     200          12 :                 num_suites++;
     201             :         }
     202             : #endif /* CONFIG_SAE */
     203             : 
     204             : #ifdef CONFIG_RSN_TESTING
     205             :         if (rsn_testing) {
     206             :                 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
     207             :                 pos += RSN_SELECTOR_LEN;
     208             :                 num_suites++;
     209             :         }
     210             : #endif /* CONFIG_RSN_TESTING */
     211             : 
     212         542 :         if (num_suites == 0) {
     213           0 :                 wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
     214             :                            conf->wpa_key_mgmt);
     215           0 :                 return -1;
     216             :         }
     217         542 :         WPA_PUT_LE16(count, num_suites);
     218             : 
     219             :         /* RSN Capabilities */
     220         542 :         capab = 0;
     221         542 :         if (conf->rsn_preauth)
     222           1 :                 capab |= WPA_CAPABILITY_PREAUTH;
     223         542 :         if (conf->peerkey)
     224           3 :                 capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
     225         542 :         if (conf->wmm_enabled) {
     226             :                 /* 4 PTKSA replay counters when using WMM */
     227         534 :                 capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
     228             :         }
     229             : #ifdef CONFIG_IEEE80211W
     230         542 :         if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
     231         131 :                 capab |= WPA_CAPABILITY_MFPC;
     232         131 :                 if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
     233          23 :                         capab |= WPA_CAPABILITY_MFPR;
     234             :         }
     235             : #endif /* CONFIG_IEEE80211W */
     236             : #ifdef CONFIG_RSN_TESTING
     237             :         if (rsn_testing)
     238             :                 capab |= BIT(8) | BIT(14) | BIT(15);
     239             : #endif /* CONFIG_RSN_TESTING */
     240         542 :         WPA_PUT_LE16(pos, capab);
     241         542 :         pos += 2;
     242             : 
     243         542 :         if (pmkid) {
     244          40 :                 if (pos + 2 + PMKID_LEN > buf + len)
     245           0 :                         return -1;
     246             :                 /* PMKID Count */
     247          40 :                 WPA_PUT_LE16(pos, 1);
     248          40 :                 pos += 2;
     249          40 :                 os_memcpy(pos, pmkid, PMKID_LEN);
     250          40 :                 pos += PMKID_LEN;
     251             :         }
     252             : 
     253             : #ifdef CONFIG_IEEE80211W
     254         542 :         if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
     255         131 :                 if (pos + 2 + 4 > buf + len)
     256           0 :                         return -1;
     257         131 :                 if (pmkid == NULL) {
     258             :                         /* PMKID Count */
     259         123 :                         WPA_PUT_LE16(pos, 0);
     260         123 :                         pos += 2;
     261             :                 }
     262             : 
     263             :                 /* Management Group Cipher Suite */
     264         131 :                 switch (conf->group_mgmt_cipher) {
     265             :                 case WPA_CIPHER_AES_128_CMAC:
     266         131 :                         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
     267         131 :                         break;
     268             :                 case WPA_CIPHER_BIP_GMAC_128:
     269           0 :                         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
     270           0 :                         break;
     271             :                 case WPA_CIPHER_BIP_GMAC_256:
     272           0 :                         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
     273           0 :                         break;
     274             :                 case WPA_CIPHER_BIP_CMAC_256:
     275           0 :                         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256);
     276           0 :                         break;
     277             :                 default:
     278           0 :                         wpa_printf(MSG_DEBUG,
     279             :                                    "Invalid group management cipher (0x%x)",
     280             :                                    conf->group_mgmt_cipher);
     281           0 :                         return -1;
     282             :                 }
     283         131 :                 pos += RSN_SELECTOR_LEN;
     284             :         }
     285             : #endif /* CONFIG_IEEE80211W */
     286             : 
     287             : #ifdef CONFIG_RSN_TESTING
     288             :         if (rsn_testing) {
     289             :                 /*
     290             :                  * Fill in any defined fields and add extra data to the end of
     291             :                  * the element.
     292             :                  */
     293             :                 int pmkid_count_set = pmkid != NULL;
     294             :                 if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
     295             :                         pmkid_count_set = 1;
     296             :                 /* PMKID Count */
     297             :                 WPA_PUT_LE16(pos, 0);
     298             :                 pos += 2;
     299             :                 if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
     300             :                         /* Management Group Cipher Suite */
     301             :                         RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
     302             :                         pos += RSN_SELECTOR_LEN;
     303             :                 }
     304             : 
     305             :                 os_memset(pos, 0x12, 17);
     306             :                 pos += 17;
     307             :         }
     308             : #endif /* CONFIG_RSN_TESTING */
     309             : 
     310         542 :         hdr->len = (pos - buf) - 2;
     311             : 
     312         542 :         return pos - buf;
     313             : }
     314             : 
     315             : 
     316           1 : static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid)
     317             : {
     318             :         u8 *len;
     319             :         u16 capab;
     320             : 
     321           1 :         *eid++ = WLAN_EID_VENDOR_SPECIFIC;
     322           1 :         len = eid++; /* to be filled */
     323           1 :         WPA_PUT_BE24(eid, OUI_WFA);
     324           1 :         eid += 3;
     325           1 :         *eid++ = HS20_OSEN_OUI_TYPE;
     326             : 
     327             :         /* Group Data Cipher Suite */
     328           1 :         RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
     329           1 :         eid += RSN_SELECTOR_LEN;
     330             : 
     331             :         /* Pairwise Cipher Suite Count and List */
     332           1 :         WPA_PUT_LE16(eid, 1);
     333           1 :         eid += 2;
     334           1 :         RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP);
     335           1 :         eid += RSN_SELECTOR_LEN;
     336             : 
     337             :         /* AKM Suite Count and List */
     338           1 :         WPA_PUT_LE16(eid, 1);
     339           1 :         eid += 2;
     340           1 :         RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN);
     341           1 :         eid += RSN_SELECTOR_LEN;
     342             : 
     343             :         /* RSN Capabilities */
     344           1 :         capab = 0;
     345           1 :         if (conf->wmm_enabled) {
     346             :                 /* 4 PTKSA replay counters when using WMM */
     347           1 :                 capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
     348             :         }
     349             : #ifdef CONFIG_IEEE80211W
     350           1 :         if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
     351           1 :                 capab |= WPA_CAPABILITY_MFPC;
     352           1 :                 if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
     353           0 :                         capab |= WPA_CAPABILITY_MFPR;
     354             :         }
     355             : #endif /* CONFIG_IEEE80211W */
     356           1 :         WPA_PUT_LE16(eid, capab);
     357           1 :         eid += 2;
     358             : 
     359           1 :         *len = eid - len - 1;
     360             : 
     361           1 :         return eid;
     362             : }
     363             : 
     364             : 
     365         510 : int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
     366             : {
     367             :         u8 *pos, buf[128];
     368             :         int res;
     369             : 
     370         510 :         pos = buf;
     371             : 
     372         510 :         if (wpa_auth->conf.wpa == WPA_PROTO_OSEN) {
     373           1 :                 pos = wpa_write_osen(&wpa_auth->conf, pos);
     374             :         }
     375         510 :         if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
     376         502 :                 res = wpa_write_rsn_ie(&wpa_auth->conf,
     377         502 :                                        pos, buf + sizeof(buf) - pos, NULL);
     378         502 :                 if (res < 0)
     379           0 :                         return res;
     380         502 :                 pos += res;
     381             :         }
     382             : #ifdef CONFIG_IEEE80211R
     383         510 :         if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) {
     384          31 :                 res = wpa_write_mdie(&wpa_auth->conf, pos,
     385          31 :                                      buf + sizeof(buf) - pos);
     386          31 :                 if (res < 0)
     387           0 :                         return res;
     388          31 :                 pos += res;
     389             :         }
     390             : #endif /* CONFIG_IEEE80211R */
     391         510 :         if (wpa_auth->conf.wpa & WPA_PROTO_WPA) {
     392          23 :                 res = wpa_write_wpa_ie(&wpa_auth->conf,
     393          23 :                                        pos, buf + sizeof(buf) - pos);
     394          23 :                 if (res < 0)
     395           0 :                         return res;
     396          23 :                 pos += res;
     397             :         }
     398             : 
     399         510 :         os_free(wpa_auth->wpa_ie);
     400         510 :         wpa_auth->wpa_ie = os_malloc(pos - buf);
     401         510 :         if (wpa_auth->wpa_ie == NULL)
     402           0 :                 return -1;
     403         510 :         os_memcpy(wpa_auth->wpa_ie, buf, pos - buf);
     404         510 :         wpa_auth->wpa_ie_len = pos - buf;
     405             : 
     406         510 :         return 0;
     407             : }
     408             : 
     409             : 
     410         736 : u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len,
     411             :                  const u8 *data2, size_t data2_len)
     412             : {
     413         736 :         *pos++ = WLAN_EID_VENDOR_SPECIFIC;
     414         736 :         *pos++ = RSN_SELECTOR_LEN + data_len + data2_len;
     415         736 :         RSN_SELECTOR_PUT(pos, kde);
     416         736 :         pos += RSN_SELECTOR_LEN;
     417         736 :         os_memcpy(pos, data, data_len);
     418         736 :         pos += data_len;
     419         736 :         if (data2) {
     420         616 :                 os_memcpy(pos, data2, data2_len);
     421         616 :                 pos += data2_len;
     422             :         }
     423         736 :         return pos;
     424             : }
     425             : 
     426             : 
     427             : struct wpa_auth_okc_iter_data {
     428             :         struct rsn_pmksa_cache_entry *pmksa;
     429             :         const u8 *aa;
     430             :         const u8 *spa;
     431             :         const u8 *pmkid;
     432             : };
     433             : 
     434             : 
     435           2 : static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
     436             : {
     437           2 :         struct wpa_auth_okc_iter_data *data = ctx;
     438           2 :         data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa,
     439             :                                           data->pmkid);
     440           2 :         if (data->pmksa)
     441           2 :                 return 1;
     442           0 :         return 0;
     443             : }
     444             : 
     445             : 
     446         656 : int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
     447             :                         struct wpa_state_machine *sm,
     448             :                         const u8 *wpa_ie, size_t wpa_ie_len,
     449             :                         const u8 *mdie, size_t mdie_len)
     450             : {
     451             :         struct wpa_ie_data data;
     452             :         int ciphers, key_mgmt, res, version;
     453             :         u32 selector;
     454             :         size_t i;
     455         656 :         const u8 *pmkid = NULL;
     456             : 
     457         656 :         if (wpa_auth == NULL || sm == NULL)
     458           0 :                 return WPA_NOT_ENABLED;
     459             : 
     460         656 :         if (wpa_ie == NULL || wpa_ie_len < 1)
     461           0 :                 return WPA_INVALID_IE;
     462             : 
     463         656 :         if (wpa_ie[0] == WLAN_EID_RSN)
     464         645 :                 version = WPA_PROTO_RSN;
     465             :         else
     466          11 :                 version = WPA_PROTO_WPA;
     467             : 
     468         656 :         if (!(wpa_auth->conf.wpa & version)) {
     469           0 :                 wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR,
     470           0 :                            version, MAC2STR(sm->addr));
     471           0 :                 return WPA_INVALID_PROTO;
     472             :         }
     473             : 
     474         656 :         if (version == WPA_PROTO_RSN) {
     475         645 :                 res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
     476             : 
     477         645 :                 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
     478             :                 if (0) {
     479             :                 }
     480             : #ifdef CONFIG_IEEE80211R
     481         645 :                 else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
     482           7 :                         selector = RSN_AUTH_KEY_MGMT_FT_802_1X;
     483         638 :                 else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK)
     484          23 :                         selector = RSN_AUTH_KEY_MGMT_FT_PSK;
     485             : #endif /* CONFIG_IEEE80211R */
     486             : #ifdef CONFIG_IEEE80211W
     487         615 :                 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
     488           3 :                         selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
     489         612 :                 else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
     490          11 :                         selector = RSN_AUTH_KEY_MGMT_PSK_SHA256;
     491             : #endif /* CONFIG_IEEE80211W */
     492             : #ifdef CONFIG_SAE
     493         601 :                 else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
     494          18 :                         selector = RSN_AUTH_KEY_MGMT_SAE;
     495         583 :                 else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
     496           6 :                         selector = RSN_AUTH_KEY_MGMT_FT_SAE;
     497             : #endif /* CONFIG_SAE */
     498         577 :                 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
     499         282 :                         selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
     500         295 :                 else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
     501         295 :                         selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
     502         645 :                 wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
     503             : 
     504         645 :                 selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
     505             :                                                data.pairwise_cipher);
     506         645 :                 if (!selector)
     507           0 :                         selector = RSN_CIPHER_SUITE_CCMP;
     508         645 :                 wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
     509             : 
     510         645 :                 selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
     511             :                                                data.group_cipher);
     512         645 :                 if (!selector)
     513           0 :                         selector = RSN_CIPHER_SUITE_CCMP;
     514         645 :                 wpa_auth->dot11RSNAGroupCipherSelected = selector;
     515             :         } else {
     516          11 :                 res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);
     517             : 
     518          11 :                 selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
     519          11 :                 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
     520           1 :                         selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
     521          10 :                 else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
     522          10 :                         selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
     523          11 :                 wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
     524             : 
     525          11 :                 selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
     526             :                                                data.pairwise_cipher);
     527          11 :                 if (!selector)
     528           0 :                         selector = RSN_CIPHER_SUITE_TKIP;
     529          11 :                 wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
     530             : 
     531          11 :                 selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
     532             :                                                data.group_cipher);
     533          11 :                 if (!selector)
     534           0 :                         selector = WPA_CIPHER_SUITE_TKIP;
     535          11 :                 wpa_auth->dot11RSNAGroupCipherSelected = selector;
     536             :         }
     537         656 :         if (res) {
     538           0 :                 wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from "
     539           0 :                            MACSTR " (res=%d)", MAC2STR(sm->addr), res);
     540           0 :                 wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len);
     541           0 :                 return WPA_INVALID_IE;
     542             :         }
     543             : 
     544         656 :         if (data.group_cipher != wpa_auth->conf.wpa_group) {
     545           0 :                 wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from "
     546           0 :                            MACSTR, data.group_cipher, MAC2STR(sm->addr));
     547           0 :                 return WPA_INVALID_GROUP;
     548             :         }
     549             : 
     550         656 :         key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
     551         656 :         if (!key_mgmt) {
     552           0 :                 wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
     553           0 :                            MACSTR, data.key_mgmt, MAC2STR(sm->addr));
     554           0 :                 return WPA_INVALID_AKMP;
     555             :         }
     556             :         if (0) {
     557             :         }
     558             : #ifdef CONFIG_IEEE80211R
     559         656 :         else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
     560           7 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
     561         649 :         else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
     562          23 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
     563             : #endif /* CONFIG_IEEE80211R */
     564             : #ifdef CONFIG_IEEE80211W
     565         626 :         else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
     566           3 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
     567         623 :         else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
     568          11 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
     569             : #endif /* CONFIG_IEEE80211W */
     570             : #ifdef CONFIG_SAE
     571         612 :         else if (key_mgmt & WPA_KEY_MGMT_SAE)
     572          18 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
     573         594 :         else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
     574           6 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
     575             : #endif /* CONFIG_SAE */
     576         588 :         else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
     577         283 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
     578             :         else
     579         305 :                 sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
     580             : 
     581         656 :         if (version == WPA_PROTO_RSN)
     582         645 :                 ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
     583             :         else
     584          11 :                 ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
     585         656 :         if (!ciphers) {
     586           0 :                 wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) "
     587             :                            "from " MACSTR,
     588             :                            version == WPA_PROTO_RSN ? "RSN" : "WPA",
     589           0 :                            data.pairwise_cipher, MAC2STR(sm->addr));
     590           0 :                 return WPA_INVALID_PAIRWISE;
     591             :         }
     592             : 
     593             : #ifdef CONFIG_IEEE80211W
     594         656 :         if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
     595          19 :                 if (!(data.capabilities & WPA_CAPABILITY_MFPC)) {
     596           0 :                         wpa_printf(MSG_DEBUG, "Management frame protection "
     597             :                                    "required, but client did not enable it");
     598           0 :                         return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
     599             :                 }
     600             : 
     601          19 :                 if (ciphers & WPA_CIPHER_TKIP) {
     602           0 :                         wpa_printf(MSG_DEBUG, "Management frame protection "
     603             :                                    "cannot use TKIP");
     604           0 :                         return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
     605             :                 }
     606             : 
     607          19 :                 if (data.mgmt_group_cipher != wpa_auth->conf.group_mgmt_cipher)
     608             :                 {
     609           0 :                         wpa_printf(MSG_DEBUG, "Unsupported management group "
     610             :                                    "cipher %d", data.mgmt_group_cipher);
     611           0 :                         return WPA_INVALID_MGMT_GROUP_CIPHER;
     612             :                 }
     613             :         }
     614             : 
     615         764 :         if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION ||
     616         108 :             !(data.capabilities & WPA_CAPABILITY_MFPC))
     617         622 :                 sm->mgmt_frame_prot = 0;
     618             :         else
     619          34 :                 sm->mgmt_frame_prot = 1;
     620             : #endif /* CONFIG_IEEE80211W */
     621             : 
     622             : #ifdef CONFIG_IEEE80211R
     623         656 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
     624          36 :                 if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
     625           0 :                         wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but "
     626             :                                    "MDIE not included");
     627           0 :                         return WPA_INVALID_MDIE;
     628             :                 }
     629          36 :                 if (os_memcmp(mdie, wpa_auth->conf.mobility_domain,
     630             :                               MOBILITY_DOMAIN_ID_LEN) != 0) {
     631           0 :                         wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown "
     632             :                                     "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN);
     633           0 :                         return WPA_INVALID_MDIE;
     634             :                 }
     635             :         }
     636             : #endif /* CONFIG_IEEE80211R */
     637             : 
     638         656 :         sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
     639         656 :         if (sm->pairwise < 0)
     640           0 :                 return WPA_INVALID_PAIRWISE;
     641             : 
     642             :         /* TODO: clear WPA/WPA2 state if STA changes from one to another */
     643         656 :         if (wpa_ie[0] == WLAN_EID_RSN)
     644         645 :                 sm->wpa = WPA_VERSION_WPA2;
     645             :         else
     646          11 :                 sm->wpa = WPA_VERSION_WPA;
     647             : 
     648         656 :         sm->pmksa = NULL;
     649         684 :         for (i = 0; i < data.num_pmkid; i++) {
     650          35 :                 wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
     651          35 :                             &data.pmkid[i * PMKID_LEN], PMKID_LEN);
     652          35 :                 sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr,
     653          35 :                                                  &data.pmkid[i * PMKID_LEN]);
     654          35 :                 if (sm->pmksa) {
     655           7 :                         pmkid = sm->pmksa->pmkid;
     656           7 :                         break;
     657             :                 }
     658             :         }
     659        1316 :         for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc &&
     660           4 :                      i < data.num_pmkid; i++) {
     661             :                 struct wpa_auth_okc_iter_data idata;
     662           2 :                 idata.pmksa = NULL;
     663           2 :                 idata.aa = wpa_auth->addr;
     664           2 :                 idata.spa = sm->addr;
     665           2 :                 idata.pmkid = &data.pmkid[i * PMKID_LEN];
     666           2 :                 wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata);
     667           2 :                 if (idata.pmksa) {
     668           2 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
     669             :                                          "OKC match for PMKID");
     670           4 :                         sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa,
     671           2 :                                                         idata.pmksa,
     672           2 :                                                         wpa_auth->addr,
     673             :                                                         idata.pmkid);
     674           2 :                         pmkid = idata.pmkid;
     675           2 :                         break;
     676             :                 }
     677             :         }
     678         656 :         if (sm->pmksa && pmkid) {
     679          18 :                 wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
     680             :                                  "PMKID found from PMKSA cache "
     681             :                                  "eap_type=%d vlan_id=%d",
     682           9 :                                  sm->pmksa->eap_type_authsrv,
     683           9 :                                  sm->pmksa->vlan_id);
     684           9 :                 os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
     685             :         }
     686             : 
     687         656 :         if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
     688         632 :                 os_free(sm->wpa_ie);
     689         632 :                 sm->wpa_ie = os_malloc(wpa_ie_len);
     690         632 :                 if (sm->wpa_ie == NULL)
     691           0 :                         return WPA_ALLOC_FAIL;
     692             :         }
     693         656 :         os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
     694         656 :         sm->wpa_ie_len = wpa_ie_len;
     695             : 
     696         656 :         return WPA_IE_OK;
     697             : }
     698             : 
     699             : 
     700             : #ifdef CONFIG_HS20
     701           2 : int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
     702             :                       struct wpa_state_machine *sm,
     703             :                       const u8 *osen_ie, size_t osen_ie_len)
     704             : {
     705           2 :         if (wpa_auth == NULL || sm == NULL)
     706           0 :                 return -1;
     707             : 
     708             :         /* TODO: parse OSEN element */
     709           2 :         sm->wpa_key_mgmt = WPA_KEY_MGMT_OSEN;
     710           2 :         sm->mgmt_frame_prot = 1;
     711           2 :         sm->pairwise = WPA_CIPHER_CCMP;
     712           2 :         sm->wpa = WPA_VERSION_WPA2;
     713             : 
     714           2 :         if (sm->wpa_ie == NULL || sm->wpa_ie_len < osen_ie_len) {
     715           2 :                 os_free(sm->wpa_ie);
     716           2 :                 sm->wpa_ie = os_malloc(osen_ie_len);
     717           2 :                 if (sm->wpa_ie == NULL)
     718           0 :                         return -1;
     719             :         }
     720             : 
     721           2 :         os_memcpy(sm->wpa_ie, osen_ie, osen_ie_len);
     722           2 :         sm->wpa_ie_len = osen_ie_len;
     723             : 
     724           2 :         return 0;
     725             : }
     726             : 
     727             : #endif /* CONFIG_HS20 */
     728             : 
     729             : 
     730             : /**
     731             :  * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
     732             :  * @pos: Pointer to the IE header
     733             :  * @end: Pointer to the end of the Key Data buffer
     734             :  * @ie: Pointer to parsed IE data
     735             :  * Returns: 0 on success, 1 if end mark is found, -1 on failure
     736             :  */
     737         159 : static int wpa_parse_generic(const u8 *pos, const u8 *end,
     738             :                              struct wpa_eapol_ie_parse *ie)
     739             : {
     740         159 :         if (pos[1] == 0)
     741           0 :                 return 1;
     742             : 
     743         185 :         if (pos[1] >= 6 &&
     744          40 :             RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
     745          28 :             pos[2 + WPA_SELECTOR_LEN] == 1 &&
     746          14 :             pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
     747          14 :                 ie->wpa_ie = pos;
     748          14 :                 ie->wpa_ie_len = pos[1] + 2;
     749          14 :                 return 0;
     750             :         }
     751             : 
     752         145 :         if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) {
     753           2 :                 ie->osen = pos;
     754           2 :                 ie->osen_len = pos[1] + 2;
     755           2 :                 return 0;
     756             :         }
     757             : 
     758         286 :         if (pos + 1 + RSN_SELECTOR_LEN < end &&
     759         144 :             pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
     760           1 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
     761           0 :                 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
     762           0 :                 return 0;
     763             :         }
     764             : 
     765         153 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     766          10 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
     767           0 :                 ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
     768           0 :                 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
     769           0 :                 return 0;
     770             :         }
     771             : 
     772         153 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     773          10 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
     774           7 :                 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
     775           7 :                 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
     776           7 :                 return 0;
     777             :         }
     778             : 
     779             : #ifdef CONFIG_PEERKEY
     780         139 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     781           3 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
     782           0 :                 ie->smk = pos + 2 + RSN_SELECTOR_LEN;
     783           0 :                 ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
     784           0 :                 return 0;
     785             :         }
     786             : 
     787         139 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     788           3 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
     789           1 :                 ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
     790           1 :                 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
     791           1 :                 return 0;
     792             :         }
     793             : 
     794         137 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     795           2 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
     796           0 :                 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
     797           0 :                 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
     798           0 :                 return 0;
     799             :         }
     800             : 
     801         137 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     802           2 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
     803           2 :                 ie->error = pos + 2 + RSN_SELECTOR_LEN;
     804           2 :                 ie->error_len = pos[1] - RSN_SELECTOR_LEN;
     805           2 :                 return 0;
     806             :         }
     807             : #endif /* CONFIG_PEERKEY */
     808             : 
     809             : #ifdef CONFIG_IEEE80211W
     810         133 :         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
     811           0 :             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
     812           0 :                 ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
     813           0 :                 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
     814           0 :                 return 0;
     815             :         }
     816             : #endif /* CONFIG_IEEE80211W */
     817             : 
     818             : #ifdef CONFIG_P2P
     819         266 :         if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
     820         133 :             RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
     821         133 :                 ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
     822         266 :                 wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
     823         266 :                             ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
     824         133 :                 return 0;
     825             :         }
     826             : 
     827           0 :         if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
     828           0 :             RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
     829           0 :                 ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
     830           0 :                 wpa_hexdump(MSG_DEBUG,
     831             :                             "WPA: IP Address Allocation in EAPOL-Key",
     832           0 :                             ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
     833           0 :                 return 0;
     834             :         }
     835             : #endif /* CONFIG_P2P */
     836             : 
     837           0 :         return 0;
     838             : }
     839             : 
     840             : 
     841             : /**
     842             :  * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
     843             :  * @buf: Pointer to the Key Data buffer
     844             :  * @len: Key Data Length
     845             :  * @ie: Pointer to parsed IE data
     846             :  * Returns: 0 on success, -1 on failure
     847             :  */
     848         656 : int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
     849             : {
     850             :         const u8 *pos, *end;
     851         656 :         int ret = 0;
     852             : 
     853         656 :         os_memset(ie, 0, sizeof(*ie));
     854        1485 :         for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
     855         988 :                 if (pos[0] == 0xdd &&
     856         318 :                     ((pos == buf + len - 1) || pos[1] == 0)) {
     857             :                         /* Ignore padding */
     858             :                         break;
     859             :                 }
     860         829 :                 if (pos + 2 + pos[1] > end) {
     861           0 :                         wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
     862             :                                    "underflow (ie=%d len=%d pos=%d)",
     863           0 :                                    pos[0], pos[1], (int) (pos - buf));
     864           0 :                         wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
     865             :                                         buf, len);
     866           0 :                         ret = -1;
     867           0 :                         break;
     868             :                 }
     869         829 :                 if (*pos == WLAN_EID_RSN) {
     870         638 :                         ie->rsn_ie = pos;
     871         638 :                         ie->rsn_ie_len = pos[1] + 2;
     872             : #ifdef CONFIG_IEEE80211R
     873         191 :                 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
     874          16 :                         ie->mdie = pos;
     875          16 :                         ie->mdie_len = pos[1] + 2;
     876         175 :                 } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
     877          16 :                         ie->ftie = pos;
     878          16 :                         ie->ftie_len = pos[1] + 2;
     879             : #endif /* CONFIG_IEEE80211R */
     880         159 :                 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
     881         159 :                         ret = wpa_parse_generic(pos, end, ie);
     882         159 :                         if (ret < 0)
     883           0 :                                 break;
     884         159 :                         if (ret > 0) {
     885           0 :                                 ret = 0;
     886           0 :                                 break;
     887             :                         }
     888             :                 } else {
     889           0 :                         wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
     890           0 :                                     "Key Data IE", pos, 2 + pos[1]);
     891             :                 }
     892             :         }
     893             : 
     894         656 :         return ret;
     895             : }
     896             : 
     897             : 
     898         657 : int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
     899             : {
     900         657 :         return sm ? sm->mgmt_frame_prot : 0;
     901             : }

Generated by: LCOV version 1.10