LCOV - code coverage report
Current view: top level - common - wpa_common.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 535 806 66.4 %
Date: 2014-10-09 Functions: 32 35 91.4 %

          Line data    Source code
       1             : /*
       2             :  * WPA/RSN - Shared functions for supplicant and authenticator
       3             :  * Copyright (c) 2002-2013, 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 "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "crypto/md5.h"
      13             : #include "crypto/sha1.h"
      14             : #include "crypto/sha256.h"
      15             : #include "crypto/aes_wrap.h"
      16             : #include "crypto/crypto.h"
      17             : #include "ieee802_11_defs.h"
      18             : #include "defs.h"
      19             : #include "wpa_common.h"
      20             : 
      21             : 
      22             : /**
      23             :  * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
      24             :  * @key: EAPOL-Key Key Confirmation Key (KCK)
      25             :  * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
      26             :  * @buf: Pointer to the beginning of the EAPOL header (version field)
      27             :  * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
      28             :  * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
      29             :  * Returns: 0 on success, -1 on failure
      30             :  *
      31             :  * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
      32             :  * to be cleared (all zeroes) when calling this function.
      33             :  *
      34             :  * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
      35             :  * description of the Key MIC calculation. It includes packet data from the
      36             :  * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
      37             :  * happened during final editing of the standard and the correct behavior is
      38             :  * defined in the last draft (IEEE 802.11i/D10).
      39             :  */
      40        1775 : int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
      41             :                       u8 *mic)
      42             : {
      43             :         u8 hash[SHA1_MAC_LEN];
      44             : 
      45        1775 :         switch (ver) {
      46             : #ifndef CONFIG_FIPS
      47             :         case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
      48          95 :                 return hmac_md5(key, 16, buf, len, mic);
      49             : #endif /* CONFIG_FIPS */
      50             :         case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
      51        1565 :                 if (hmac_sha1(key, 16, buf, len, hash))
      52           0 :                         return -1;
      53        1565 :                 os_memcpy(mic, hash, MD5_MAC_LEN);
      54        1565 :                 break;
      55             : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
      56             :         case WPA_KEY_INFO_TYPE_AES_128_CMAC:
      57         109 :                 return omac1_aes_128(key, buf, len, mic);
      58             : #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
      59             : #ifdef CONFIG_HS20
      60             :         case WPA_KEY_INFO_TYPE_AKM_DEFINED:
      61             :                 /* FIX: This should be based on negotiated AKM */
      62           6 :                 return omac1_aes_128(key, buf, len, mic);
      63             : #endif /* CONFIG_HS20 */
      64             :         default:
      65           0 :                 return -1;
      66             :         }
      67             : 
      68        1565 :         return 0;
      69             : }
      70             : 
      71             : 
      72             : /**
      73             :  * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
      74             :  * @pmk: Pairwise master key
      75             :  * @pmk_len: Length of PMK
      76             :  * @label: Label to use in derivation
      77             :  * @addr1: AA or SA
      78             :  * @addr2: SA or AA
      79             :  * @nonce1: ANonce or SNonce
      80             :  * @nonce2: SNonce or ANonce
      81             :  * @ptk: Buffer for pairwise transient key
      82             :  * @ptk_len: Length of PTK
      83             :  * @use_sha256: Whether to use SHA256-based KDF
      84             :  *
      85             :  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
      86             :  * PTK = PRF-X(PMK, "Pairwise key expansion",
      87             :  *             Min(AA, SA) || Max(AA, SA) ||
      88             :  *             Min(ANonce, SNonce) || Max(ANonce, SNonce))
      89             :  *
      90             :  * STK = PRF-X(SMK, "Peer key expansion",
      91             :  *             Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
      92             :  *             Min(INonce, PNonce) || Max(INonce, PNonce))
      93             :  */
      94         551 : void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
      95             :                     const u8 *addr1, const u8 *addr2,
      96             :                     const u8 *nonce1, const u8 *nonce2,
      97             :                     u8 *ptk, size_t ptk_len, int use_sha256)
      98             : {
      99             :         u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
     100             : 
     101         551 :         if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
     102          28 :                 os_memcpy(data, addr1, ETH_ALEN);
     103          28 :                 os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
     104             :         } else {
     105         523 :                 os_memcpy(data, addr2, ETH_ALEN);
     106         523 :                 os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
     107             :         }
     108             : 
     109         551 :         if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
     110         273 :                 os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
     111         273 :                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
     112             :                           WPA_NONCE_LEN);
     113             :         } else {
     114         278 :                 os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
     115         278 :                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
     116             :                           WPA_NONCE_LEN);
     117             :         }
     118             : 
     119             : #ifdef CONFIG_IEEE80211W
     120         551 :         if (use_sha256)
     121          17 :                 sha256_prf(pmk, pmk_len, label, data, sizeof(data),
     122             :                            ptk, ptk_len);
     123             :         else
     124             : #endif /* CONFIG_IEEE80211W */
     125         534 :                 sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk,
     126             :                          ptk_len);
     127             : 
     128        6612 :         wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
     129        6612 :                    MAC2STR(addr1), MAC2STR(addr2));
     130         551 :         wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
     131         551 :         wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
     132         551 :         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
     133         551 :         wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
     134         551 : }
     135             : 
     136             : 
     137             : #ifdef CONFIG_IEEE80211R
     138         442 : int wpa_ft_mic(const u8 *kck, const u8 *sta_addr, const u8 *ap_addr,
     139             :                u8 transaction_seqnum, const u8 *mdie, size_t mdie_len,
     140             :                const u8 *ftie, size_t ftie_len,
     141             :                const u8 *rsnie, size_t rsnie_len,
     142             :                const u8 *ric, size_t ric_len, u8 *mic)
     143             : {
     144             :         u8 *buf, *pos;
     145             :         size_t buf_len;
     146             : 
     147         442 :         buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
     148         442 :         buf = os_malloc(buf_len);
     149         442 :         if (buf == NULL)
     150           0 :                 return -1;
     151             : 
     152         442 :         pos = buf;
     153         442 :         os_memcpy(pos, sta_addr, ETH_ALEN);
     154         442 :         pos += ETH_ALEN;
     155         442 :         os_memcpy(pos, ap_addr, ETH_ALEN);
     156         442 :         pos += ETH_ALEN;
     157         442 :         *pos++ = transaction_seqnum;
     158         442 :         if (rsnie) {
     159         442 :                 os_memcpy(pos, rsnie, rsnie_len);
     160         442 :                 pos += rsnie_len;
     161             :         }
     162         442 :         if (mdie) {
     163         442 :                 os_memcpy(pos, mdie, mdie_len);
     164         442 :                 pos += mdie_len;
     165             :         }
     166         442 :         if (ftie) {
     167             :                 struct rsn_ftie *_ftie;
     168         442 :                 os_memcpy(pos, ftie, ftie_len);
     169         442 :                 if (ftie_len < 2 + sizeof(*_ftie)) {
     170           0 :                         os_free(buf);
     171           0 :                         return -1;
     172             :                 }
     173         442 :                 _ftie = (struct rsn_ftie *) (pos + 2);
     174         442 :                 os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
     175         442 :                 pos += ftie_len;
     176             :         }
     177         442 :         if (ric) {
     178           0 :                 os_memcpy(pos, ric, ric_len);
     179           0 :                 pos += ric_len;
     180             :         }
     181             : 
     182         442 :         wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
     183         442 :         if (omac1_aes_128(kck, buf, pos - buf, mic)) {
     184           0 :                 os_free(buf);
     185           0 :                 return -1;
     186             :         }
     187             : 
     188         442 :         os_free(buf);
     189             : 
     190         442 :         return 0;
     191             : }
     192             : 
     193             : 
     194         671 : static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
     195             :                              struct wpa_ft_ies *parse)
     196             : {
     197             :         const u8 *end, *pos;
     198             : 
     199         671 :         parse->ftie = ie;
     200         671 :         parse->ftie_len = ie_len;
     201             : 
     202         671 :         pos = ie + sizeof(struct rsn_ftie);
     203         671 :         end = ie + ie_len;
     204             : 
     205        2455 :         while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
     206        1113 :                 switch (pos[0]) {
     207             :                 case FTIE_SUBELEM_R1KH_ID:
     208         442 :                         if (pos[1] != FT_R1KH_ID_LEN) {
     209           0 :                                 wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
     210           0 :                                            "length in FTIE: %d", pos[1]);
     211           0 :                                 return -1;
     212             :                         }
     213         442 :                         parse->r1kh_id = pos + 2;
     214         442 :                         break;
     215             :                 case FTIE_SUBELEM_GTK:
     216           0 :                         parse->gtk = pos + 2;
     217           0 :                         parse->gtk_len = pos[1];
     218           0 :                         break;
     219             :                 case FTIE_SUBELEM_R0KH_ID:
     220         671 :                         if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
     221           0 :                                 wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
     222           0 :                                            "length in FTIE: %d", pos[1]);
     223           0 :                                 return -1;
     224             :                         }
     225         671 :                         parse->r0kh_id = pos + 2;
     226         671 :                         parse->r0kh_id_len = pos[1];
     227         671 :                         break;
     228             : #ifdef CONFIG_IEEE80211W
     229             :                 case FTIE_SUBELEM_IGTK:
     230           0 :                         parse->igtk = pos + 2;
     231           0 :                         parse->igtk_len = pos[1];
     232           0 :                         break;
     233             : #endif /* CONFIG_IEEE80211W */
     234             :                 }
     235             : 
     236        1113 :                 pos += 2 + pos[1];
     237             :         }
     238             : 
     239         671 :         return 0;
     240             : }
     241             : 
     242             : 
     243         690 : int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
     244             :                      struct wpa_ft_ies *parse)
     245             : {
     246             :         const u8 *end, *pos;
     247             :         struct wpa_ie_data data;
     248             :         int ret;
     249             :         const struct rsn_ftie *ftie;
     250         690 :         int prot_ie_count = 0;
     251             : 
     252         690 :         os_memset(parse, 0, sizeof(*parse));
     253         690 :         if (ies == NULL)
     254           0 :                 return 0;
     255             : 
     256         690 :         pos = ies;
     257         690 :         end = ies + ies_len;
     258        5756 :         while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
     259        4376 :                 switch (pos[0]) {
     260             :                 case WLAN_EID_RSN:
     261         690 :                         parse->rsn = pos + 2;
     262         690 :                         parse->rsn_len = pos[1];
     263         690 :                         ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
     264         690 :                                                    parse->rsn_len + 2,
     265             :                                                    &data);
     266         690 :                         if (ret < 0) {
     267           0 :                                 wpa_printf(MSG_DEBUG, "FT: Failed to parse "
     268             :                                            "RSN IE: %d", ret);
     269           0 :                                 return -1;
     270             :                         }
     271         690 :                         if (data.num_pmkid == 1 && data.pmkid)
     272         671 :                                 parse->rsn_pmkid = data.pmkid;
     273         690 :                         break;
     274             :                 case WLAN_EID_MOBILITY_DOMAIN:
     275         690 :                         parse->mdie = pos + 2;
     276         690 :                         parse->mdie_len = pos[1];
     277         690 :                         break;
     278             :                 case WLAN_EID_FAST_BSS_TRANSITION:
     279         671 :                         if (pos[1] < sizeof(*ftie))
     280           0 :                                 return -1;
     281         671 :                         ftie = (const struct rsn_ftie *) (pos + 2);
     282         671 :                         prot_ie_count = ftie->mic_control[1];
     283         671 :                         if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
     284           0 :                                 return -1;
     285         671 :                         break;
     286             :                 case WLAN_EID_TIMEOUT_INTERVAL:
     287           0 :                         parse->tie = pos + 2;
     288           0 :                         parse->tie_len = pos[1];
     289           0 :                         break;
     290             :                 case WLAN_EID_RIC_DATA:
     291           0 :                         if (parse->ric == NULL)
     292           0 :                                 parse->ric = pos;
     293           0 :                         break;
     294             :                 }
     295             : 
     296        4376 :                 pos += 2 + pos[1];
     297             :         }
     298             : 
     299         690 :         if (prot_ie_count == 0)
     300         248 :                 return 0; /* no MIC */
     301             : 
     302             :         /*
     303             :          * Check that the protected IE count matches with IEs included in the
     304             :          * frame.
     305             :          */
     306         442 :         if (parse->rsn)
     307         442 :                 prot_ie_count--;
     308         442 :         if (parse->mdie)
     309         442 :                 prot_ie_count--;
     310         442 :         if (parse->ftie)
     311         442 :                 prot_ie_count--;
     312         442 :         if (prot_ie_count < 0) {
     313           0 :                 wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
     314             :                            "the protected IE count");
     315           0 :                 return -1;
     316             :         }
     317             : 
     318         442 :         if (prot_ie_count == 0 && parse->ric) {
     319           0 :                 wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
     320             :                            "included in protected IE count");
     321           0 :                 return -1;
     322             :         }
     323             : 
     324             :         /* Determine the end of the RIC IE(s) */
     325         442 :         pos = parse->ric;
     326         884 :         while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
     327             :                prot_ie_count) {
     328           0 :                 prot_ie_count--;
     329           0 :                 pos += 2 + pos[1];
     330             :         }
     331         442 :         parse->ric_len = pos - parse->ric;
     332         442 :         if (prot_ie_count) {
     333           0 :                 wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
     334             :                            "frame", (int) prot_ie_count);
     335           0 :                 return -1;
     336             :         }
     337             : 
     338         442 :         return 0;
     339             : }
     340             : #endif /* CONFIG_IEEE80211R */
     341             : 
     342             : 
     343        3575 : static int rsn_selector_to_bitfield(const u8 *s)
     344             : {
     345        3575 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
     346           0 :                 return WPA_CIPHER_NONE;
     347        3575 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
     348           0 :                 return WPA_CIPHER_WEP40;
     349        3575 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
     350          31 :                 return WPA_CIPHER_TKIP;
     351        3544 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
     352        3481 :                 return WPA_CIPHER_CCMP;
     353          63 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
     354           0 :                 return WPA_CIPHER_WEP104;
     355             : #ifdef CONFIG_IEEE80211W
     356          63 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
     357          63 :                 return WPA_CIPHER_AES_128_CMAC;
     358             : #endif /* CONFIG_IEEE80211W */
     359           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
     360           0 :                 return WPA_CIPHER_GCMP;
     361           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
     362           0 :                 return WPA_CIPHER_CCMP_256;
     363           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
     364           0 :                 return WPA_CIPHER_GCMP_256;
     365           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
     366           0 :                 return WPA_CIPHER_BIP_GMAC_128;
     367           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
     368           0 :                 return WPA_CIPHER_BIP_GMAC_256;
     369           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
     370           0 :                 return WPA_CIPHER_BIP_CMAC_256;
     371           0 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
     372           0 :                 return WPA_CIPHER_GTK_NOT_USED;
     373           0 :         return 0;
     374             : }
     375             : 
     376             : 
     377        1756 : static int rsn_key_mgmt_to_bitfield(const u8 *s)
     378             : {
     379        1756 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
     380         561 :                 return WPA_KEY_MGMT_IEEE8021X;
     381        1195 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
     382         176 :                 return WPA_KEY_MGMT_PSK;
     383             : #ifdef CONFIG_IEEE80211R
     384        1019 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
     385          32 :                 return WPA_KEY_MGMT_FT_IEEE8021X;
     386         987 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
     387         929 :                 return WPA_KEY_MGMT_FT_PSK;
     388             : #endif /* CONFIG_IEEE80211R */
     389             : #ifdef CONFIG_IEEE80211W
     390          58 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
     391           3 :                 return WPA_KEY_MGMT_IEEE8021X_SHA256;
     392          55 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
     393          11 :                 return WPA_KEY_MGMT_PSK_SHA256;
     394             : #endif /* CONFIG_IEEE80211W */
     395             : #ifdef CONFIG_SAE
     396          44 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
     397          18 :                 return WPA_KEY_MGMT_SAE;
     398          26 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
     399          26 :                 return WPA_KEY_MGMT_FT_SAE;
     400             : #endif /* CONFIG_SAE */
     401           0 :         return 0;
     402             : }
     403             : 
     404             : 
     405        1756 : static int wpa_cipher_valid_group(int cipher)
     406             : {
     407        3512 :         return wpa_cipher_valid_pairwise(cipher) ||
     408           0 :                 cipher == WPA_CIPHER_WEP104 ||
     409        1756 :                 cipher == WPA_CIPHER_WEP40 ||
     410             :                 cipher == WPA_CIPHER_GTK_NOT_USED;
     411             : }
     412             : 
     413             : 
     414             : #ifdef CONFIG_IEEE80211W
     415          63 : int wpa_cipher_valid_mgmt_group(int cipher)
     416             : {
     417          63 :         return cipher == WPA_CIPHER_AES_128_CMAC ||
     418           0 :                 cipher == WPA_CIPHER_BIP_GMAC_128 ||
     419          63 :                 cipher == WPA_CIPHER_BIP_GMAC_256 ||
     420             :                 cipher == WPA_CIPHER_BIP_CMAC_256;
     421             : }
     422             : #endif /* CONFIG_IEEE80211W */
     423             : 
     424             : 
     425             : /**
     426             :  * wpa_parse_wpa_ie_rsn - Parse RSN IE
     427             :  * @rsn_ie: Buffer containing RSN IE
     428             :  * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
     429             :  * @data: Pointer to structure that will be filled in with parsed data
     430             :  * Returns: 0 on success, <0 on failure
     431             :  */
     432        1756 : int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
     433             :                          struct wpa_ie_data *data)
     434             : {
     435             :         const struct rsn_ie_hdr *hdr;
     436             :         const u8 *pos;
     437             :         int left;
     438             :         int i, count;
     439             : 
     440        1756 :         os_memset(data, 0, sizeof(*data));
     441        1756 :         data->proto = WPA_PROTO_RSN;
     442        1756 :         data->pairwise_cipher = WPA_CIPHER_CCMP;
     443        1756 :         data->group_cipher = WPA_CIPHER_CCMP;
     444        1756 :         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
     445        1756 :         data->capabilities = 0;
     446        1756 :         data->pmkid = NULL;
     447        1756 :         data->num_pmkid = 0;
     448             : #ifdef CONFIG_IEEE80211W
     449        1756 :         data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
     450             : #else /* CONFIG_IEEE80211W */
     451             :         data->mgmt_group_cipher = 0;
     452             : #endif /* CONFIG_IEEE80211W */
     453             : 
     454        1756 :         if (rsn_ie_len == 0) {
     455             :                 /* No RSN IE - fail silently */
     456           0 :                 return -1;
     457             :         }
     458             : 
     459        1756 :         if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
     460           0 :                 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
     461             :                            __func__, (unsigned long) rsn_ie_len);
     462           0 :                 return -1;
     463             :         }
     464             : 
     465        1756 :         hdr = (const struct rsn_ie_hdr *) rsn_ie;
     466             : 
     467        3512 :         if (hdr->elem_id != WLAN_EID_RSN ||
     468        3512 :             hdr->len != rsn_ie_len - 2 ||
     469        1756 :             WPA_GET_LE16(hdr->version) != RSN_VERSION) {
     470           0 :                 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
     471             :                            __func__);
     472           0 :                 return -2;
     473             :         }
     474             : 
     475        1756 :         pos = (const u8 *) (hdr + 1);
     476        1756 :         left = rsn_ie_len - sizeof(*hdr);
     477             : 
     478        1756 :         if (left >= RSN_SELECTOR_LEN) {
     479        1756 :                 data->group_cipher = rsn_selector_to_bitfield(pos);
     480        1756 :                 if (!wpa_cipher_valid_group(data->group_cipher)) {
     481           0 :                         wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x",
     482             :                                    __func__, data->group_cipher);
     483           0 :                         return -1;
     484             :                 }
     485        1756 :                 pos += RSN_SELECTOR_LEN;
     486        1756 :                 left -= RSN_SELECTOR_LEN;
     487           0 :         } else if (left > 0) {
     488           0 :                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
     489             :                            __func__, left);
     490           0 :                 return -3;
     491             :         }
     492             : 
     493        1756 :         if (left >= 2) {
     494        1756 :                 data->pairwise_cipher = 0;
     495        1756 :                 count = WPA_GET_LE16(pos);
     496        1756 :                 pos += 2;
     497        1756 :                 left -= 2;
     498        1756 :                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
     499           0 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
     500             :                                    "count %u left %u", __func__, count, left);
     501           0 :                         return -4;
     502             :                 }
     503        3512 :                 for (i = 0; i < count; i++) {
     504        1756 :                         data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
     505        1756 :                         pos += RSN_SELECTOR_LEN;
     506        1756 :                         left -= RSN_SELECTOR_LEN;
     507             :                 }
     508             : #ifdef CONFIG_IEEE80211W
     509        1756 :                 if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
     510           0 :                         wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
     511             :                                    "pairwise cipher", __func__);
     512           0 :                         return -1;
     513             :                 }
     514             : #endif /* CONFIG_IEEE80211W */
     515           0 :         } else if (left == 1) {
     516           0 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
     517             :                            __func__);
     518           0 :                 return -5;
     519             :         }
     520             : 
     521        1756 :         if (left >= 2) {
     522        1756 :                 data->key_mgmt = 0;
     523        1756 :                 count = WPA_GET_LE16(pos);
     524        1756 :                 pos += 2;
     525        1756 :                 left -= 2;
     526        1756 :                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
     527           0 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
     528             :                                    "count %u left %u", __func__, count, left);
     529           0 :                         return -6;
     530             :                 }
     531        3512 :                 for (i = 0; i < count; i++) {
     532        1756 :                         data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
     533        1756 :                         pos += RSN_SELECTOR_LEN;
     534        1756 :                         left -= RSN_SELECTOR_LEN;
     535             :                 }
     536           0 :         } else if (left == 1) {
     537           0 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
     538             :                            __func__);
     539           0 :                 return -7;
     540             :         }
     541             : 
     542        1756 :         if (left >= 2) {
     543        1756 :                 data->capabilities = WPA_GET_LE16(pos);
     544        1756 :                 pos += 2;
     545        1756 :                 left -= 2;
     546             :         }
     547             : 
     548        1756 :         if (left >= 2) {
     549        1001 :                 data->num_pmkid = WPA_GET_LE16(pos);
     550        1001 :                 pos += 2;
     551        1001 :                 left -= 2;
     552        1001 :                 if (left < (int) data->num_pmkid * PMKID_LEN) {
     553           0 :                         wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
     554             :                                    "(num_pmkid=%lu left=%d)",
     555             :                                    __func__, (unsigned long) data->num_pmkid,
     556             :                                    left);
     557           0 :                         data->num_pmkid = 0;
     558           0 :                         return -9;
     559             :                 } else {
     560        1001 :                         data->pmkid = pos;
     561        1001 :                         pos += data->num_pmkid * PMKID_LEN;
     562        1001 :                         left -= data->num_pmkid * PMKID_LEN;
     563             :                 }
     564             :         }
     565             : 
     566             : #ifdef CONFIG_IEEE80211W
     567        1756 :         if (left >= 4) {
     568          63 :                 data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
     569          63 :                 if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
     570           0 :                         wpa_printf(MSG_DEBUG, "%s: Unsupported management "
     571             :                                    "group cipher 0x%x", __func__,
     572             :                                    data->mgmt_group_cipher);
     573           0 :                         return -10;
     574             :                 }
     575          63 :                 pos += RSN_SELECTOR_LEN;
     576          63 :                 left -= RSN_SELECTOR_LEN;
     577             :         }
     578             : #endif /* CONFIG_IEEE80211W */
     579             : 
     580        1756 :         if (left > 0) {
     581           0 :                 wpa_hexdump(MSG_DEBUG,
     582             :                             "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
     583             :                             pos, left);
     584             :         }
     585             : 
     586        1756 :         return 0;
     587             : }
     588             : 
     589             : 
     590          26 : static int wpa_selector_to_bitfield(const u8 *s)
     591             : {
     592          26 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
     593           0 :                 return WPA_CIPHER_NONE;
     594          26 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
     595           0 :                 return WPA_CIPHER_WEP40;
     596          26 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
     597          24 :                 return WPA_CIPHER_TKIP;
     598           2 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
     599           2 :                 return WPA_CIPHER_CCMP;
     600           0 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
     601           0 :                 return WPA_CIPHER_WEP104;
     602           0 :         return 0;
     603             : }
     604             : 
     605             : 
     606          13 : static int wpa_key_mgmt_to_bitfield(const u8 *s)
     607             : {
     608          13 :         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
     609           1 :                 return WPA_KEY_MGMT_IEEE8021X;
     610          12 :         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
     611          12 :                 return WPA_KEY_MGMT_PSK;
     612           0 :         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
     613           0 :                 return WPA_KEY_MGMT_WPA_NONE;
     614           0 :         return 0;
     615             : }
     616             : 
     617             : 
     618          13 : int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
     619             :                          struct wpa_ie_data *data)
     620             : {
     621             :         const struct wpa_ie_hdr *hdr;
     622             :         const u8 *pos;
     623             :         int left;
     624             :         int i, count;
     625             : 
     626          13 :         os_memset(data, 0, sizeof(*data));
     627          13 :         data->proto = WPA_PROTO_WPA;
     628          13 :         data->pairwise_cipher = WPA_CIPHER_TKIP;
     629          13 :         data->group_cipher = WPA_CIPHER_TKIP;
     630          13 :         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
     631          13 :         data->capabilities = 0;
     632          13 :         data->pmkid = NULL;
     633          13 :         data->num_pmkid = 0;
     634          13 :         data->mgmt_group_cipher = 0;
     635             : 
     636          13 :         if (wpa_ie_len == 0) {
     637             :                 /* No WPA IE - fail silently */
     638           0 :                 return -1;
     639             :         }
     640             : 
     641          13 :         if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
     642           0 :                 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
     643             :                            __func__, (unsigned long) wpa_ie_len);
     644           0 :                 return -1;
     645             :         }
     646             : 
     647          13 :         hdr = (const struct wpa_ie_hdr *) wpa_ie;
     648             : 
     649          26 :         if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
     650          26 :             hdr->len != wpa_ie_len - 2 ||
     651          26 :             RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
     652          13 :             WPA_GET_LE16(hdr->version) != WPA_VERSION) {
     653           0 :                 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
     654             :                            __func__);
     655           0 :                 return -2;
     656             :         }
     657             : 
     658          13 :         pos = (const u8 *) (hdr + 1);
     659          13 :         left = wpa_ie_len - sizeof(*hdr);
     660             : 
     661          13 :         if (left >= WPA_SELECTOR_LEN) {
     662          13 :                 data->group_cipher = wpa_selector_to_bitfield(pos);
     663          13 :                 pos += WPA_SELECTOR_LEN;
     664          13 :                 left -= WPA_SELECTOR_LEN;
     665           0 :         } else if (left > 0) {
     666           0 :                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
     667             :                            __func__, left);
     668           0 :                 return -3;
     669             :         }
     670             : 
     671          13 :         if (left >= 2) {
     672          13 :                 data->pairwise_cipher = 0;
     673          13 :                 count = WPA_GET_LE16(pos);
     674          13 :                 pos += 2;
     675          13 :                 left -= 2;
     676          13 :                 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
     677           0 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
     678             :                                    "count %u left %u", __func__, count, left);
     679           0 :                         return -4;
     680             :                 }
     681          26 :                 for (i = 0; i < count; i++) {
     682          13 :                         data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
     683          13 :                         pos += WPA_SELECTOR_LEN;
     684          13 :                         left -= WPA_SELECTOR_LEN;
     685             :                 }
     686           0 :         } else if (left == 1) {
     687           0 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
     688             :                            __func__);
     689           0 :                 return -5;
     690             :         }
     691             : 
     692          13 :         if (left >= 2) {
     693          13 :                 data->key_mgmt = 0;
     694          13 :                 count = WPA_GET_LE16(pos);
     695          13 :                 pos += 2;
     696          13 :                 left -= 2;
     697          13 :                 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
     698           0 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
     699             :                                    "count %u left %u", __func__, count, left);
     700           0 :                         return -6;
     701             :                 }
     702          26 :                 for (i = 0; i < count; i++) {
     703          13 :                         data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
     704          13 :                         pos += WPA_SELECTOR_LEN;
     705          13 :                         left -= WPA_SELECTOR_LEN;
     706             :                 }
     707           0 :         } else if (left == 1) {
     708           0 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
     709             :                            __func__);
     710           0 :                 return -7;
     711             :         }
     712             : 
     713          13 :         if (left >= 2) {
     714           0 :                 data->capabilities = WPA_GET_LE16(pos);
     715           0 :                 pos += 2;
     716           0 :                 left -= 2;
     717             :         }
     718             : 
     719          13 :         if (left > 0) {
     720           0 :                 wpa_hexdump(MSG_DEBUG,
     721             :                             "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
     722             :                             pos, left);
     723             :         }
     724             : 
     725          13 :         return 0;
     726             : }
     727             : 
     728             : 
     729             : #ifdef CONFIG_IEEE80211R
     730             : 
     731             : /**
     732             :  * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
     733             :  *
     734             :  * IEEE Std 802.11r-2008 - 8.5.1.5.3
     735             :  */
     736          19 : void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
     737             :                        const u8 *ssid, size_t ssid_len,
     738             :                        const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
     739             :                        const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
     740             : {
     741             :         u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
     742             :                FT_R0KH_ID_MAX_LEN + ETH_ALEN];
     743             :         u8 *pos, r0_key_data[48], hash[32];
     744             :         const u8 *addr[2];
     745             :         size_t len[2];
     746             : 
     747             :         /*
     748             :          * R0-Key-Data = KDF-384(XXKey, "FT-R0",
     749             :          *                       SSIDlength || SSID || MDID || R0KHlength ||
     750             :          *                       R0KH-ID || S0KH-ID)
     751             :          * XXKey is either the second 256 bits of MSK or PSK.
     752             :          * PMK-R0 = L(R0-Key-Data, 0, 256)
     753             :          * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
     754             :          */
     755          19 :         if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
     756          19 :                 return;
     757          19 :         pos = buf;
     758          19 :         *pos++ = ssid_len;
     759          19 :         os_memcpy(pos, ssid, ssid_len);
     760          19 :         pos += ssid_len;
     761          19 :         os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
     762          19 :         pos += MOBILITY_DOMAIN_ID_LEN;
     763          19 :         *pos++ = r0kh_id_len;
     764          19 :         os_memcpy(pos, r0kh_id, r0kh_id_len);
     765          19 :         pos += r0kh_id_len;
     766          19 :         os_memcpy(pos, s0kh_id, ETH_ALEN);
     767          19 :         pos += ETH_ALEN;
     768             : 
     769          19 :         sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
     770             :                    r0_key_data, sizeof(r0_key_data));
     771          19 :         os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
     772             : 
     773             :         /*
     774             :          * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
     775             :          */
     776          19 :         addr[0] = (const u8 *) "FT-R0N";
     777          19 :         len[0] = 6;
     778          19 :         addr[1] = r0_key_data + PMK_LEN;
     779          19 :         len[1] = 16;
     780             : 
     781          19 :         sha256_vector(2, addr, len, hash);
     782          19 :         os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
     783             : }
     784             : 
     785             : 
     786             : /**
     787             :  * wpa_derive_pmk_r1_name - Derive PMKR1Name
     788             :  *
     789             :  * IEEE Std 802.11r-2008 - 8.5.1.5.4
     790             :  */
     791         264 : void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
     792             :                             const u8 *s1kh_id, u8 *pmk_r1_name)
     793             : {
     794             :         u8 hash[32];
     795             :         const u8 *addr[4];
     796             :         size_t len[4];
     797             : 
     798             :         /*
     799             :          * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
     800             :          *                                  R1KH-ID || S1KH-ID))
     801             :          */
     802         264 :         addr[0] = (const u8 *) "FT-R1N";
     803         264 :         len[0] = 6;
     804         264 :         addr[1] = pmk_r0_name;
     805         264 :         len[1] = WPA_PMK_NAME_LEN;
     806         264 :         addr[2] = r1kh_id;
     807         264 :         len[2] = FT_R1KH_ID_LEN;
     808         264 :         addr[3] = s1kh_id;
     809         264 :         len[3] = ETH_ALEN;
     810             : 
     811         264 :         sha256_vector(4, addr, len, hash);
     812         264 :         os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
     813         264 : }
     814             : 
     815             : 
     816             : /**
     817             :  * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
     818             :  *
     819             :  * IEEE Std 802.11r-2008 - 8.5.1.5.4
     820             :  */
     821          35 : void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
     822             :                        const u8 *r1kh_id, const u8 *s1kh_id,
     823             :                        u8 *pmk_r1, u8 *pmk_r1_name)
     824             : {
     825             :         u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
     826             :         u8 *pos;
     827             : 
     828             :         /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
     829          35 :         pos = buf;
     830          35 :         os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
     831          35 :         pos += FT_R1KH_ID_LEN;
     832          35 :         os_memcpy(pos, s1kh_id, ETH_ALEN);
     833          35 :         pos += ETH_ALEN;
     834             : 
     835          35 :         sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
     836             : 
     837          35 :         wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
     838          35 : }
     839             : 
     840             : 
     841             : /**
     842             :  * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
     843             :  *
     844             :  * IEEE Std 802.11r-2008 - 8.5.1.5.5
     845             :  */
     846         240 : void wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
     847             :                        const u8 *sta_addr, const u8 *bssid,
     848             :                        const u8 *pmk_r1_name,
     849             :                        u8 *ptk, size_t ptk_len, u8 *ptk_name)
     850             : {
     851             :         u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
     852             :         u8 *pos, hash[32];
     853             :         const u8 *addr[6];
     854             :         size_t len[6];
     855             : 
     856             :         /*
     857             :          * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
     858             :          *                  BSSID || STA-ADDR)
     859             :          */
     860         240 :         pos = buf;
     861         240 :         os_memcpy(pos, snonce, WPA_NONCE_LEN);
     862         240 :         pos += WPA_NONCE_LEN;
     863         240 :         os_memcpy(pos, anonce, WPA_NONCE_LEN);
     864         240 :         pos += WPA_NONCE_LEN;
     865         240 :         os_memcpy(pos, bssid, ETH_ALEN);
     866         240 :         pos += ETH_ALEN;
     867         240 :         os_memcpy(pos, sta_addr, ETH_ALEN);
     868         240 :         pos += ETH_ALEN;
     869             : 
     870         240 :         sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, ptk, ptk_len);
     871             : 
     872             :         /*
     873             :          * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
     874             :          *                                ANonce || BSSID || STA-ADDR))
     875             :          */
     876         240 :         addr[0] = pmk_r1_name;
     877         240 :         len[0] = WPA_PMK_NAME_LEN;
     878         240 :         addr[1] = (const u8 *) "FT-PTKN";
     879         240 :         len[1] = 7;
     880         240 :         addr[2] = snonce;
     881         240 :         len[2] = WPA_NONCE_LEN;
     882         240 :         addr[3] = anonce;
     883         240 :         len[3] = WPA_NONCE_LEN;
     884         240 :         addr[4] = bssid;
     885         240 :         len[4] = ETH_ALEN;
     886         240 :         addr[5] = sta_addr;
     887         240 :         len[5] = ETH_ALEN;
     888             : 
     889         240 :         sha256_vector(6, addr, len, hash);
     890         240 :         os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
     891         240 : }
     892             : 
     893             : #endif /* CONFIG_IEEE80211R */
     894             : 
     895             : 
     896             : /**
     897             :  * rsn_pmkid - Calculate PMK identifier
     898             :  * @pmk: Pairwise master key
     899             :  * @pmk_len: Length of pmk in bytes
     900             :  * @aa: Authenticator address
     901             :  * @spa: Supplicant address
     902             :  * @pmkid: Buffer for PMKID
     903             :  * @use_sha256: Whether to use SHA256-based KDF
     904             :  *
     905             :  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
     906             :  * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
     907             :  */
     908         604 : void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
     909             :                u8 *pmkid, int use_sha256)
     910             : {
     911         604 :         char *title = "PMK Name";
     912             :         const u8 *addr[3];
     913         604 :         const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
     914             :         unsigned char hash[SHA256_MAC_LEN];
     915             : 
     916         604 :         addr[0] = (u8 *) title;
     917         604 :         addr[1] = aa;
     918         604 :         addr[2] = spa;
     919             : 
     920             : #ifdef CONFIG_IEEE80211W
     921         604 :         if (use_sha256)
     922           6 :                 hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
     923             :         else
     924             : #endif /* CONFIG_IEEE80211W */
     925         598 :                 hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
     926         604 :         os_memcpy(pmkid, hash, PMKID_LEN);
     927         604 : }
     928             : 
     929             : 
     930             : /**
     931             :  * wpa_cipher_txt - Convert cipher suite to a text string
     932             :  * @cipher: Cipher suite (WPA_CIPHER_* enum)
     933             :  * Returns: Pointer to a text string of the cipher suite name
     934             :  */
     935          10 : const char * wpa_cipher_txt(int cipher)
     936             : {
     937          10 :         switch (cipher) {
     938             :         case WPA_CIPHER_NONE:
     939           0 :                 return "NONE";
     940             :         case WPA_CIPHER_WEP40:
     941           0 :                 return "WEP-40";
     942             :         case WPA_CIPHER_WEP104:
     943           0 :                 return "WEP-104";
     944             :         case WPA_CIPHER_TKIP:
     945           2 :                 return "TKIP";
     946             :         case WPA_CIPHER_CCMP:
     947           8 :                 return "CCMP";
     948             :         case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
     949           0 :                 return "CCMP+TKIP";
     950             :         case WPA_CIPHER_GCMP:
     951           0 :                 return "GCMP";
     952             :         case WPA_CIPHER_GCMP_256:
     953           0 :                 return "GCMP-256";
     954             :         case WPA_CIPHER_CCMP_256:
     955           0 :                 return "CCMP-256";
     956             :         case WPA_CIPHER_GTK_NOT_USED:
     957           0 :                 return "GTK_NOT_USED";
     958             :         default:
     959           0 :                 return "UNKNOWN";
     960             :         }
     961             : }
     962             : 
     963             : 
     964             : /**
     965             :  * wpa_key_mgmt_txt - Convert key management suite to a text string
     966             :  * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
     967             :  * @proto: WPA/WPA2 version (WPA_PROTO_*)
     968             :  * Returns: Pointer to a text string of the key management suite name
     969             :  */
     970           0 : const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
     971             : {
     972           0 :         switch (key_mgmt) {
     973             :         case WPA_KEY_MGMT_IEEE8021X:
     974           0 :                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
     975           0 :                         return "WPA2+WPA/IEEE 802.1X/EAP";
     976           0 :                 return proto == WPA_PROTO_RSN ?
     977           0 :                         "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
     978             :         case WPA_KEY_MGMT_PSK:
     979           0 :                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
     980           0 :                         return "WPA2-PSK+WPA-PSK";
     981           0 :                 return proto == WPA_PROTO_RSN ?
     982           0 :                         "WPA2-PSK" : "WPA-PSK";
     983             :         case WPA_KEY_MGMT_NONE:
     984           0 :                 return "NONE";
     985             :         case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
     986           0 :                 return "IEEE 802.1X (no WPA)";
     987             : #ifdef CONFIG_IEEE80211R
     988             :         case WPA_KEY_MGMT_FT_IEEE8021X:
     989           0 :                 return "FT-EAP";
     990             :         case WPA_KEY_MGMT_FT_PSK:
     991           0 :                 return "FT-PSK";
     992             : #endif /* CONFIG_IEEE80211R */
     993             : #ifdef CONFIG_IEEE80211W
     994             :         case WPA_KEY_MGMT_IEEE8021X_SHA256:
     995           0 :                 return "WPA2-EAP-SHA256";
     996             :         case WPA_KEY_MGMT_PSK_SHA256:
     997           0 :                 return "WPA2-PSK-SHA256";
     998             : #endif /* CONFIG_IEEE80211W */
     999             :         default:
    1000           0 :                 return "UNKNOWN";
    1001             :         }
    1002             : }
    1003             : 
    1004             : 
    1005        2209 : u32 wpa_akm_to_suite(int akm)
    1006             : {
    1007        2209 :         if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
    1008          14 :                 return WLAN_AKM_SUITE_FT_8021X;
    1009        2195 :         if (akm & WPA_KEY_MGMT_FT_PSK)
    1010           0 :                 return WLAN_AKM_SUITE_FT_PSK;
    1011        2195 :         if (akm & WPA_KEY_MGMT_IEEE8021X)
    1012        2184 :                 return WLAN_AKM_SUITE_8021X;
    1013          11 :         if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
    1014          11 :                 return WLAN_AKM_SUITE_8021X_SHA256;
    1015           0 :         if (akm & WPA_KEY_MGMT_IEEE8021X)
    1016           0 :                 return WLAN_AKM_SUITE_8021X;
    1017           0 :         if (akm & WPA_KEY_MGMT_PSK_SHA256)
    1018           0 :                 return WLAN_AKM_SUITE_PSK_SHA256;
    1019           0 :         if (akm & WPA_KEY_MGMT_PSK)
    1020           0 :                 return WLAN_AKM_SUITE_PSK;
    1021           0 :         if (akm & WPA_KEY_MGMT_CCKM)
    1022           0 :                 return WLAN_AKM_SUITE_CCKM;
    1023           0 :         if (akm & WPA_KEY_MGMT_OSEN)
    1024           0 :                 return WLAN_AKM_SUITE_OSEN;
    1025           0 :         return 0;
    1026             : }
    1027             : 
    1028             : 
    1029         570 : int wpa_compare_rsn_ie(int ft_initial_assoc,
    1030             :                        const u8 *ie1, size_t ie1len,
    1031             :                        const u8 *ie2, size_t ie2len)
    1032             : {
    1033         570 :         if (ie1 == NULL || ie2 == NULL)
    1034           0 :                 return -1;
    1035             : 
    1036         570 :         if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
    1037         551 :                 return 0; /* identical IEs */
    1038             : 
    1039             : #ifdef CONFIG_IEEE80211R
    1040          19 :         if (ft_initial_assoc) {
    1041             :                 struct wpa_ie_data ie1d, ie2d;
    1042             :                 /*
    1043             :                  * The PMKID-List in RSN IE is different between Beacon/Probe
    1044             :                  * Response/(Re)Association Request frames and EAPOL-Key
    1045             :                  * messages in FT initial mobility domain association. Allow
    1046             :                  * for this, but verify that other parts of the RSN IEs are
    1047             :                  * identical.
    1048             :                  */
    1049          38 :                 if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
    1050          19 :                     wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
    1051          19 :                         return -1;
    1052          38 :                 if (ie1d.proto == ie2d.proto &&
    1053          38 :                     ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
    1054          38 :                     ie1d.group_cipher == ie2d.group_cipher &&
    1055          38 :                     ie1d.key_mgmt == ie2d.key_mgmt &&
    1056          38 :                     ie1d.capabilities == ie2d.capabilities &&
    1057          19 :                     ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
    1058          19 :                         return 0;
    1059             :         }
    1060             : #endif /* CONFIG_IEEE80211R */
    1061             : 
    1062           0 :         return -1;
    1063             : }
    1064             : 
    1065             : 
    1066             : #ifdef CONFIG_IEEE80211R
    1067          19 : int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
    1068             : {
    1069             :         u8 *start, *end, *rpos, *rend;
    1070          19 :         int added = 0;
    1071             : 
    1072          19 :         start = ies;
    1073          19 :         end = ies + ies_len;
    1074             : 
    1075          38 :         while (start < end) {
    1076          19 :                 if (*start == WLAN_EID_RSN)
    1077          19 :                         break;
    1078           0 :                 start += 2 + start[1];
    1079             :         }
    1080          19 :         if (start >= end) {
    1081           0 :                 wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
    1082             :                            "IEs data");
    1083           0 :                 return -1;
    1084             :         }
    1085          19 :         wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
    1086          19 :                     start, 2 + start[1]);
    1087             : 
    1088             :         /* Find start of PMKID-Count */
    1089          19 :         rpos = start + 2;
    1090          19 :         rend = rpos + start[1];
    1091             : 
    1092             :         /* Skip Version and Group Data Cipher Suite */
    1093          19 :         rpos += 2 + 4;
    1094             :         /* Skip Pairwise Cipher Suite Count and List */
    1095          19 :         rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
    1096             :         /* Skip AKM Suite Count and List */
    1097          19 :         rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
    1098             : 
    1099          19 :         if (rpos == rend) {
    1100             :                 /* Add RSN Capabilities */
    1101           0 :                 os_memmove(rpos + 2, rpos, end - rpos);
    1102           0 :                 *rpos++ = 0;
    1103           0 :                 *rpos++ = 0;
    1104             :         } else {
    1105             :                 /* Skip RSN Capabilities */
    1106          19 :                 rpos += 2;
    1107          19 :                 if (rpos > rend) {
    1108           0 :                         wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
    1109             :                                    "IEs data");
    1110           0 :                         return -1;
    1111             :                 }
    1112             :         }
    1113             : 
    1114          19 :         if (rpos == rend) {
    1115             :                 /* No PMKID-Count field included; add it */
    1116          14 :                 os_memmove(rpos + 2 + PMKID_LEN, rpos, end - rpos);
    1117          14 :                 WPA_PUT_LE16(rpos, 1);
    1118          14 :                 rpos += 2;
    1119          14 :                 os_memcpy(rpos, pmkid, PMKID_LEN);
    1120          14 :                 added += 2 + PMKID_LEN;
    1121          14 :                 start[1] += 2 + PMKID_LEN;
    1122             :         } else {
    1123             :                 /* PMKID-Count was included; use it */
    1124           5 :                 if (WPA_GET_LE16(rpos) != 0) {
    1125           0 :                         wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
    1126             :                                    "in RSN IE in EAPOL-Key data");
    1127           0 :                         return -1;
    1128             :                 }
    1129           5 :                 WPA_PUT_LE16(rpos, 1);
    1130           5 :                 rpos += 2;
    1131           5 :                 os_memmove(rpos + PMKID_LEN, rpos, end - rpos);
    1132           5 :                 os_memcpy(rpos, pmkid, PMKID_LEN);
    1133           5 :                 added += PMKID_LEN;
    1134           5 :                 start[1] += PMKID_LEN;
    1135             :         }
    1136             : 
    1137          19 :         wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
    1138          19 :                     "(PMKID inserted)", start, 2 + start[1]);
    1139             : 
    1140          19 :         return added;
    1141             : }
    1142             : #endif /* CONFIG_IEEE80211R */
    1143             : 
    1144             : 
    1145        4228 : int wpa_cipher_key_len(int cipher)
    1146             : {
    1147        4228 :         switch (cipher) {
    1148             :         case WPA_CIPHER_CCMP_256:
    1149             :         case WPA_CIPHER_GCMP_256:
    1150             :         case WPA_CIPHER_BIP_GMAC_256:
    1151             :         case WPA_CIPHER_BIP_CMAC_256:
    1152           0 :                 return 32;
    1153             :         case WPA_CIPHER_CCMP:
    1154             :         case WPA_CIPHER_GCMP:
    1155             :         case WPA_CIPHER_AES_128_CMAC:
    1156             :         case WPA_CIPHER_BIP_GMAC_128:
    1157        4110 :                 return 16;
    1158             :         case WPA_CIPHER_TKIP:
    1159         118 :                 return 32;
    1160             :         case WPA_CIPHER_WEP104:
    1161           0 :                 return 13;
    1162             :         case WPA_CIPHER_WEP40:
    1163           0 :                 return 5;
    1164             :         }
    1165             : 
    1166           0 :         return 0;
    1167             : }
    1168             : 
    1169             : 
    1170           0 : int wpa_cipher_rsc_len(int cipher)
    1171             : {
    1172           0 :         switch (cipher) {
    1173             :         case WPA_CIPHER_CCMP_256:
    1174             :         case WPA_CIPHER_GCMP_256:
    1175             :         case WPA_CIPHER_CCMP:
    1176             :         case WPA_CIPHER_GCMP:
    1177             :         case WPA_CIPHER_TKIP:
    1178           0 :                 return 6;
    1179             :         case WPA_CIPHER_WEP104:
    1180             :         case WPA_CIPHER_WEP40:
    1181           0 :                 return 0;
    1182             :         }
    1183             : 
    1184           0 :         return 0;
    1185             : }
    1186             : 
    1187             : 
    1188        2035 : int wpa_cipher_to_alg(int cipher)
    1189             : {
    1190        2035 :         switch (cipher) {
    1191             :         case WPA_CIPHER_CCMP_256:
    1192           0 :                 return WPA_ALG_CCMP_256;
    1193             :         case WPA_CIPHER_GCMP_256:
    1194           0 :                 return WPA_ALG_GCMP_256;
    1195             :         case WPA_CIPHER_CCMP:
    1196        1755 :                 return WPA_ALG_CCMP;
    1197             :         case WPA_CIPHER_GCMP:
    1198           0 :                 return WPA_ALG_GCMP;
    1199             :         case WPA_CIPHER_TKIP:
    1200          70 :                 return WPA_ALG_TKIP;
    1201             :         case WPA_CIPHER_WEP104:
    1202             :         case WPA_CIPHER_WEP40:
    1203           0 :                 return WPA_ALG_WEP;
    1204             :         case WPA_CIPHER_AES_128_CMAC:
    1205         210 :                 return WPA_ALG_IGTK;
    1206             :         case WPA_CIPHER_BIP_GMAC_128:
    1207           0 :                 return WPA_ALG_BIP_GMAC_128;
    1208             :         case WPA_CIPHER_BIP_GMAC_256:
    1209           0 :                 return WPA_ALG_BIP_GMAC_256;
    1210             :         case WPA_CIPHER_BIP_CMAC_256:
    1211           0 :                 return WPA_ALG_BIP_CMAC_256;
    1212             :         }
    1213           0 :         return WPA_ALG_NONE;
    1214             : }
    1215             : 
    1216             : 
    1217        2198 : int wpa_cipher_valid_pairwise(int cipher)
    1218             : {
    1219        4396 :         return cipher == WPA_CIPHER_CCMP_256 ||
    1220        2198 :                 cipher == WPA_CIPHER_GCMP_256 ||
    1221          29 :                 cipher == WPA_CIPHER_CCMP ||
    1222        2227 :                 cipher == WPA_CIPHER_GCMP ||
    1223             :                 cipher == WPA_CIPHER_TKIP;
    1224             : }
    1225             : 
    1226             : 
    1227        7891 : u32 wpa_cipher_to_suite(int proto, int cipher)
    1228             : {
    1229        7891 :         if (cipher & WPA_CIPHER_CCMP_256)
    1230           0 :                 return RSN_CIPHER_SUITE_CCMP_256;
    1231        7891 :         if (cipher & WPA_CIPHER_GCMP_256)
    1232           0 :                 return RSN_CIPHER_SUITE_GCMP_256;
    1233        7891 :         if (cipher & WPA_CIPHER_CCMP)
    1234        7246 :                 return (proto == WPA_PROTO_RSN ?
    1235        7246 :                         RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
    1236         645 :         if (cipher & WPA_CIPHER_GCMP)
    1237           0 :                 return RSN_CIPHER_SUITE_GCMP;
    1238         645 :         if (cipher & WPA_CIPHER_TKIP)
    1239         129 :                 return (proto == WPA_PROTO_RSN ?
    1240         129 :                         RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
    1241         516 :         if (cipher & WPA_CIPHER_WEP104)
    1242           0 :                 return (proto == WPA_PROTO_RSN ?
    1243           0 :                         RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
    1244         516 :         if (cipher & WPA_CIPHER_WEP40)
    1245           0 :                 return (proto == WPA_PROTO_RSN ?
    1246           0 :                         RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
    1247         516 :         if (cipher & WPA_CIPHER_NONE)
    1248           0 :                 return (proto == WPA_PROTO_RSN ?
    1249           0 :                         RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
    1250         516 :         if (cipher & WPA_CIPHER_GTK_NOT_USED)
    1251           0 :                 return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
    1252         516 :         if (cipher & WPA_CIPHER_AES_128_CMAC)
    1253         516 :                 return RSN_CIPHER_SUITE_AES_128_CMAC;
    1254           0 :         if (cipher & WPA_CIPHER_BIP_GMAC_128)
    1255           0 :                 return RSN_CIPHER_SUITE_BIP_GMAC_128;
    1256           0 :         if (cipher & WPA_CIPHER_BIP_GMAC_256)
    1257           0 :                 return RSN_CIPHER_SUITE_BIP_GMAC_256;
    1258           0 :         if (cipher & WPA_CIPHER_BIP_CMAC_256)
    1259           0 :                 return RSN_CIPHER_SUITE_BIP_CMAC_256;
    1260           0 :         return 0;
    1261             : }
    1262             : 
    1263             : 
    1264         871 : int rsn_cipher_put_suites(u8 *start, int ciphers)
    1265             : {
    1266         871 :         u8 *pos = start;
    1267             : 
    1268         871 :         if (ciphers & WPA_CIPHER_CCMP_256) {
    1269           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
    1270           0 :                 pos += RSN_SELECTOR_LEN;
    1271             :         }
    1272         871 :         if (ciphers & WPA_CIPHER_GCMP_256) {
    1273           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
    1274           0 :                 pos += RSN_SELECTOR_LEN;
    1275             :         }
    1276         871 :         if (ciphers & WPA_CIPHER_CCMP) {
    1277         870 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
    1278         870 :                 pos += RSN_SELECTOR_LEN;
    1279             :         }
    1280         871 :         if (ciphers & WPA_CIPHER_GCMP) {
    1281           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
    1282           0 :                 pos += RSN_SELECTOR_LEN;
    1283             :         }
    1284         871 :         if (ciphers & WPA_CIPHER_TKIP) {
    1285          12 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
    1286          12 :                 pos += RSN_SELECTOR_LEN;
    1287             :         }
    1288         871 :         if (ciphers & WPA_CIPHER_NONE) {
    1289           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
    1290           0 :                 pos += RSN_SELECTOR_LEN;
    1291             :         }
    1292             : 
    1293         871 :         return (pos - start) / RSN_SELECTOR_LEN;
    1294             : }
    1295             : 
    1296             : 
    1297          24 : int wpa_cipher_put_suites(u8 *start, int ciphers)
    1298             : {
    1299          24 :         u8 *pos = start;
    1300             : 
    1301          24 :         if (ciphers & WPA_CIPHER_CCMP) {
    1302          11 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
    1303          11 :                 pos += WPA_SELECTOR_LEN;
    1304             :         }
    1305          24 :         if (ciphers & WPA_CIPHER_TKIP) {
    1306          23 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
    1307          23 :                 pos += WPA_SELECTOR_LEN;
    1308             :         }
    1309          24 :         if (ciphers & WPA_CIPHER_NONE) {
    1310           0 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
    1311           0 :                 pos += WPA_SELECTOR_LEN;
    1312             :         }
    1313             : 
    1314          24 :         return (pos - start) / RSN_SELECTOR_LEN;
    1315             : }
    1316             : 
    1317             : 
    1318        1022 : int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
    1319             : {
    1320        1022 :         if (ciphers & WPA_CIPHER_CCMP_256)
    1321           0 :                 return WPA_CIPHER_CCMP_256;
    1322        1022 :         if (ciphers & WPA_CIPHER_GCMP_256)
    1323           0 :                 return WPA_CIPHER_GCMP_256;
    1324        1022 :         if (ciphers & WPA_CIPHER_CCMP)
    1325        1008 :                 return WPA_CIPHER_CCMP;
    1326          14 :         if (ciphers & WPA_CIPHER_GCMP)
    1327           0 :                 return WPA_CIPHER_GCMP;
    1328          14 :         if (ciphers & WPA_CIPHER_TKIP)
    1329          14 :                 return WPA_CIPHER_TKIP;
    1330           0 :         if (none_allowed && (ciphers & WPA_CIPHER_NONE))
    1331           0 :                 return WPA_CIPHER_NONE;
    1332           0 :         return -1;
    1333             : }
    1334             : 
    1335             : 
    1336           0 : int wpa_pick_group_cipher(int ciphers)
    1337             : {
    1338           0 :         if (ciphers & WPA_CIPHER_CCMP_256)
    1339           0 :                 return WPA_CIPHER_CCMP_256;
    1340           0 :         if (ciphers & WPA_CIPHER_GCMP_256)
    1341           0 :                 return WPA_CIPHER_GCMP_256;
    1342           0 :         if (ciphers & WPA_CIPHER_CCMP)
    1343           0 :                 return WPA_CIPHER_CCMP;
    1344           0 :         if (ciphers & WPA_CIPHER_GCMP)
    1345           0 :                 return WPA_CIPHER_GCMP;
    1346           0 :         if (ciphers & WPA_CIPHER_GTK_NOT_USED)
    1347           0 :                 return WPA_CIPHER_GTK_NOT_USED;
    1348           0 :         if (ciphers & WPA_CIPHER_TKIP)
    1349           0 :                 return WPA_CIPHER_TKIP;
    1350           0 :         if (ciphers & WPA_CIPHER_WEP104)
    1351           0 :                 return WPA_CIPHER_WEP104;
    1352           0 :         if (ciphers & WPA_CIPHER_WEP40)
    1353           0 :                 return WPA_CIPHER_WEP40;
    1354           0 :         return -1;
    1355             : }
    1356             : 
    1357             : 
    1358         441 : int wpa_parse_cipher(const char *value)
    1359             : {
    1360         441 :         int val = 0, last;
    1361             :         char *start, *end, *buf;
    1362             : 
    1363         441 :         buf = os_strdup(value);
    1364         441 :         if (buf == NULL)
    1365           0 :                 return -1;
    1366         441 :         start = buf;
    1367             : 
    1368         884 :         while (*start != '\0') {
    1369         892 :                 while (*start == ' ' || *start == '\t')
    1370           6 :                         start++;
    1371         443 :                 if (*start == '\0')
    1372           1 :                         break;
    1373         442 :                 end = start;
    1374        2657 :                 while (*end != ' ' && *end != '\t' && *end != '\0')
    1375        1773 :                         end++;
    1376         442 :                 last = *end == '\0';
    1377         442 :                 *end = '\0';
    1378         442 :                 if (os_strcmp(start, "CCMP-256") == 0)
    1379           0 :                         val |= WPA_CIPHER_CCMP_256;
    1380         442 :                 else if (os_strcmp(start, "GCMP-256") == 0)
    1381           0 :                         val |= WPA_CIPHER_GCMP_256;
    1382         442 :                 else if (os_strcmp(start, "CCMP") == 0)
    1383         419 :                         val |= WPA_CIPHER_CCMP;
    1384          23 :                 else if (os_strcmp(start, "GCMP") == 0)
    1385           0 :                         val |= WPA_CIPHER_GCMP;
    1386          23 :                 else if (os_strcmp(start, "TKIP") == 0)
    1387          16 :                         val |= WPA_CIPHER_TKIP;
    1388           7 :                 else if (os_strcmp(start, "WEP104") == 0)
    1389           2 :                         val |= WPA_CIPHER_WEP104;
    1390           5 :                 else if (os_strcmp(start, "WEP40") == 0)
    1391           2 :                         val |= WPA_CIPHER_WEP40;
    1392           3 :                 else if (os_strcmp(start, "NONE") == 0)
    1393           2 :                         val |= WPA_CIPHER_NONE;
    1394           1 :                 else if (os_strcmp(start, "GTK_NOT_USED") == 0)
    1395           0 :                         val |= WPA_CIPHER_GTK_NOT_USED;
    1396             :                 else {
    1397           1 :                         os_free(buf);
    1398           1 :                         return -1;
    1399             :                 }
    1400             : 
    1401         441 :                 if (last)
    1402         439 :                         break;
    1403           2 :                 start = end + 1;
    1404             :         }
    1405         440 :         os_free(buf);
    1406             : 
    1407         440 :         return val;
    1408             : }
    1409             : 
    1410             : 
    1411          12 : int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
    1412             : {
    1413          12 :         char *pos = start;
    1414             :         int ret;
    1415             : 
    1416          12 :         if (ciphers & WPA_CIPHER_CCMP_256) {
    1417           0 :                 ret = os_snprintf(pos, end - pos, "%sCCMP-256",
    1418             :                                   pos == start ? "" : delim);
    1419           0 :                 if (ret < 0 || ret >= end - pos)
    1420           0 :                         return -1;
    1421           0 :                 pos += ret;
    1422             :         }
    1423          12 :         if (ciphers & WPA_CIPHER_GCMP_256) {
    1424           0 :                 ret = os_snprintf(pos, end - pos, "%sGCMP-256",
    1425             :                                   pos == start ? "" : delim);
    1426           0 :                 if (ret < 0 || ret >= end - pos)
    1427           0 :                         return -1;
    1428           0 :                 pos += ret;
    1429             :         }
    1430          12 :         if (ciphers & WPA_CIPHER_CCMP) {
    1431          11 :                 ret = os_snprintf(pos, end - pos, "%sCCMP",
    1432             :                                   pos == start ? "" : delim);
    1433          11 :                 if (ret < 0 || ret >= end - pos)
    1434           0 :                         return -1;
    1435          11 :                 pos += ret;
    1436             :         }
    1437          12 :         if (ciphers & WPA_CIPHER_GCMP) {
    1438           0 :                 ret = os_snprintf(pos, end - pos, "%sGCMP",
    1439             :                                   pos == start ? "" : delim);
    1440           0 :                 if (ret < 0 || ret >= end - pos)
    1441           0 :                         return -1;
    1442           0 :                 pos += ret;
    1443             :         }
    1444          12 :         if (ciphers & WPA_CIPHER_TKIP) {
    1445           3 :                 ret = os_snprintf(pos, end - pos, "%sTKIP",
    1446             :                                   pos == start ? "" : delim);
    1447           3 :                 if (ret < 0 || ret >= end - pos)
    1448           0 :                         return -1;
    1449           3 :                 pos += ret;
    1450             :         }
    1451          12 :         if (ciphers & WPA_CIPHER_WEP104) {
    1452           0 :                 ret = os_snprintf(pos, end - pos, "%sWEP104",
    1453             :                                   pos == start ? "" : delim);
    1454           0 :                 if (ret < 0 || ret >= end - pos)
    1455           0 :                         return -1;
    1456           0 :                 pos += ret;
    1457             :         }
    1458          12 :         if (ciphers & WPA_CIPHER_WEP40) {
    1459           0 :                 ret = os_snprintf(pos, end - pos, "%sWEP40",
    1460             :                                   pos == start ? "" : delim);
    1461           0 :                 if (ret < 0 || ret >= end - pos)
    1462           0 :                         return -1;
    1463           0 :                 pos += ret;
    1464             :         }
    1465          12 :         if (ciphers & WPA_CIPHER_NONE) {
    1466           0 :                 ret = os_snprintf(pos, end - pos, "%sNONE",
    1467             :                                   pos == start ? "" : delim);
    1468           0 :                 if (ret < 0 || ret >= end - pos)
    1469           0 :                         return -1;
    1470           0 :                 pos += ret;
    1471             :         }
    1472             : 
    1473          12 :         return pos - start;
    1474             : }
    1475             : 
    1476             : 
    1477       11659 : int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
    1478             : {
    1479       11659 :         int pairwise = 0;
    1480             : 
    1481             :         /* Select group cipher based on the enabled pairwise cipher suites */
    1482       11659 :         if (wpa & 1)
    1483          91 :                 pairwise |= wpa_pairwise;
    1484       11659 :         if (wpa & 2)
    1485        5850 :                 pairwise |= rsn_pairwise;
    1486             : 
    1487       11659 :         if (pairwise & WPA_CIPHER_TKIP)
    1488          72 :                 return WPA_CIPHER_TKIP;
    1489       11587 :         if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
    1490           0 :                 return WPA_CIPHER_GCMP;
    1491       11587 :         if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
    1492             :                          WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
    1493           0 :                 return WPA_CIPHER_GCMP_256;
    1494       11587 :         if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
    1495             :                          WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
    1496           0 :                 return WPA_CIPHER_CCMP_256;
    1497       11587 :         return WPA_CIPHER_CCMP;
    1498             : }

Generated by: LCOV version 1.10