LCOV - code coverage report
Current view: top level - src/common - wpa_common.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 631 786 80.3 %
Date: 2014-05-28 Functions: 34 34 100.0 %

          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        3916 : 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        3916 :         switch (ver) {
      46             : #ifndef CONFIG_FIPS
      47             :         case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
      48         156 :                 return hmac_md5(key, 16, buf, len, mic);
      49             : #endif /* CONFIG_FIPS */
      50             :         case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
      51        3566 :                 if (hmac_sha1(key, 16, buf, len, hash))
      52           0 :                         return -1;
      53        3566 :                 os_memcpy(mic, hash, MD5_MAC_LEN);
      54        3566 :                 break;
      55             : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
      56             :         case WPA_KEY_INFO_TYPE_AES_128_CMAC:
      57         182 :                 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          12 :                 return omac1_aes_128(key, buf, len, mic);
      63             : #endif /* CONFIG_HS20 */
      64             :         default:
      65           0 :                 return -1;
      66             :         }
      67             : 
      68        3566 :         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        1272 : 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        1272 :         if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
     102         638 :                 os_memcpy(data, addr1, ETH_ALEN);
     103         638 :                 os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
     104             :         } else {
     105         634 :                 os_memcpy(data, addr2, ETH_ALEN);
     106         634 :                 os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
     107             :         }
     108             : 
     109        1272 :         if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
     110         638 :                 os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
     111         638 :                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
     112             :                           WPA_NONCE_LEN);
     113             :         } else {
     114         634 :                 os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
     115         634 :                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
     116             :                           WPA_NONCE_LEN);
     117             :         }
     118             : 
     119             : #ifdef CONFIG_IEEE80211W
     120        1272 :         if (use_sha256)
     121          32 :                 sha256_prf(pmk, pmk_len, label, data, sizeof(data),
     122             :                            ptk, ptk_len);
     123             :         else
     124             : #endif /* CONFIG_IEEE80211W */
     125        1240 :                 sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk,
     126             :                          ptk_len);
     127             : 
     128       15264 :         wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
     129       15264 :                    MAC2STR(addr1), MAC2STR(addr2));
     130        1272 :         wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
     131        1272 :         wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
     132        1272 :         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
     133        1272 :         wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
     134        1272 : }
     135             : 
     136             : 
     137             : #ifdef CONFIG_IEEE80211R
     138          80 : 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          80 :         buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
     148          80 :         buf = os_malloc(buf_len);
     149          80 :         if (buf == NULL)
     150           0 :                 return -1;
     151             : 
     152          80 :         pos = buf;
     153          80 :         os_memcpy(pos, sta_addr, ETH_ALEN);
     154          80 :         pos += ETH_ALEN;
     155          80 :         os_memcpy(pos, ap_addr, ETH_ALEN);
     156          80 :         pos += ETH_ALEN;
     157          80 :         *pos++ = transaction_seqnum;
     158          80 :         if (rsnie) {
     159          80 :                 os_memcpy(pos, rsnie, rsnie_len);
     160          80 :                 pos += rsnie_len;
     161             :         }
     162          80 :         if (mdie) {
     163          80 :                 os_memcpy(pos, mdie, mdie_len);
     164          80 :                 pos += mdie_len;
     165             :         }
     166          80 :         if (ftie) {
     167             :                 struct rsn_ftie *_ftie;
     168          80 :                 os_memcpy(pos, ftie, ftie_len);
     169          80 :                 if (ftie_len < 2 + sizeof(*_ftie)) {
     170           0 :                         os_free(buf);
     171           0 :                         return -1;
     172             :                 }
     173          80 :                 _ftie = (struct rsn_ftie *) (pos + 2);
     174          80 :                 os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
     175          80 :                 pos += ftie_len;
     176             :         }
     177          80 :         if (ric) {
     178           0 :                 os_memcpy(pos, ric, ric_len);
     179           0 :                 pos += ric_len;
     180             :         }
     181             : 
     182          80 :         wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
     183          80 :         if (omac1_aes_128(kck, buf, pos - buf, mic)) {
     184           0 :                 os_free(buf);
     185           0 :                 return -1;
     186             :         }
     187             : 
     188          80 :         os_free(buf);
     189             : 
     190          80 :         return 0;
     191             : }
     192             : 
     193             : 
     194         143 : 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         143 :         parse->ftie = ie;
     200         143 :         parse->ftie_len = ie_len;
     201             : 
     202         143 :         pos = ie + sizeof(struct rsn_ftie);
     203         143 :         end = ie + ie_len;
     204             : 
     205         593 :         while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
     206         307 :                 switch (pos[0]) {
     207             :                 case FTIE_SUBELEM_R1KH_ID:
     208         116 :                         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         116 :                         parse->r1kh_id = pos + 2;
     214         116 :                         break;
     215             :                 case FTIE_SUBELEM_GTK:
     216          40 :                         parse->gtk = pos + 2;
     217          40 :                         parse->gtk_len = pos[1];
     218          40 :                         break;
     219             :                 case FTIE_SUBELEM_R0KH_ID:
     220         143 :                         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         143 :                         parse->r0kh_id = pos + 2;
     226         143 :                         parse->r0kh_id_len = pos[1];
     227         143 :                         break;
     228             : #ifdef CONFIG_IEEE80211W
     229             :                 case FTIE_SUBELEM_IGTK:
     230           8 :                         parse->igtk = pos + 2;
     231           8 :                         parse->igtk_len = pos[1];
     232           8 :                         break;
     233             : #endif /* CONFIG_IEEE80211W */
     234             :                 }
     235             : 
     236         307 :                 pos += 2 + pos[1];
     237             :         }
     238             : 
     239         143 :         return 0;
     240             : }
     241             : 
     242             : 
     243        2225 : 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        2225 :         int prot_ie_count = 0;
     251             : 
     252        2225 :         os_memset(parse, 0, sizeof(*parse));
     253        2225 :         if (ies == NULL)
     254        1041 :                 return 0;
     255             : 
     256        1184 :         pos = ies;
     257        1184 :         end = ies + ies_len;
     258       10660 :         while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
     259        8292 :                 switch (pos[0]) {
     260             :                 case WLAN_EID_RSN:
     261         143 :                         parse->rsn = pos + 2;
     262         143 :                         parse->rsn_len = pos[1];
     263         143 :                         ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
     264         143 :                                                    parse->rsn_len + 2,
     265             :                                                    &data);
     266         143 :                         if (ret < 0) {
     267           0 :                                 wpa_printf(MSG_DEBUG, "FT: Failed to parse "
     268             :                                            "RSN IE: %d", ret);
     269           0 :                                 return -1;
     270             :                         }
     271         143 :                         if (data.num_pmkid == 1 && data.pmkid)
     272         127 :                                 parse->rsn_pmkid = data.pmkid;
     273         143 :                         break;
     274             :                 case WLAN_EID_MOBILITY_DOMAIN:
     275         189 :                         parse->mdie = pos + 2;
     276         189 :                         parse->mdie_len = pos[1];
     277         189 :                         break;
     278             :                 case WLAN_EID_FAST_BSS_TRANSITION:
     279         143 :                         if (pos[1] < sizeof(*ftie))
     280           0 :                                 return -1;
     281         143 :                         ftie = (const struct rsn_ftie *) (pos + 2);
     282         143 :                         prot_ie_count = ftie->mic_control[1];
     283         143 :                         if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
     284           0 :                                 return -1;
     285         143 :                         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        8292 :                 pos += 2 + pos[1];
     297             :         }
     298             : 
     299        1184 :         if (prot_ie_count == 0)
     300        1104 :                 return 0; /* no MIC */
     301             : 
     302             :         /*
     303             :          * Check that the protected IE count matches with IEs included in the
     304             :          * frame.
     305             :          */
     306          80 :         if (parse->rsn)
     307          80 :                 prot_ie_count--;
     308          80 :         if (parse->mdie)
     309          80 :                 prot_ie_count--;
     310          80 :         if (parse->ftie)
     311          80 :                 prot_ie_count--;
     312          80 :         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          80 :         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          80 :         pos = parse->ric;
     326         160 :         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          80 :         parse->ric_len = pos - parse->ric;
     332          80 :         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          80 :         return 0;
     339             : }
     340             : #endif /* CONFIG_IEEE80211R */
     341             : 
     342             : 
     343        6506 : static int rsn_selector_to_bitfield(const u8 *s)
     344             : {
     345        6506 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
     346           0 :                 return WPA_CIPHER_NONE;
     347        6506 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
     348           0 :                 return WPA_CIPHER_WEP40;
     349        6506 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
     350         162 :                 return WPA_CIPHER_TKIP;
     351        6344 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
     352        5828 :                 return WPA_CIPHER_CCMP;
     353         516 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
     354           0 :                 return WPA_CIPHER_WEP104;
     355             : #ifdef CONFIG_IEEE80211W
     356         516 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
     357         471 :                 return WPA_CIPHER_AES_128_CMAC;
     358             : #endif /* CONFIG_IEEE80211W */
     359          45 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
     360           1 :                 return WPA_CIPHER_GCMP;
     361          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
     362           0 :                 return WPA_CIPHER_CCMP_256;
     363          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
     364           0 :                 return WPA_CIPHER_GCMP_256;
     365          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
     366           0 :                 return WPA_CIPHER_BIP_GMAC_128;
     367          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
     368           0 :                 return WPA_CIPHER_BIP_GMAC_256;
     369          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
     370           0 :                 return WPA_CIPHER_BIP_CMAC_256;
     371          44 :         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
     372          42 :                 return WPA_CIPHER_GTK_NOT_USED;
     373           2 :         return 0;
     374             : }
     375             : 
     376             : 
     377        3058 : static int rsn_key_mgmt_to_bitfield(const u8 *s)
     378             : {
     379        3058 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
     380        1259 :                 return WPA_KEY_MGMT_IEEE8021X;
     381        1799 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
     382        1148 :                 return WPA_KEY_MGMT_PSK;
     383             : #ifdef CONFIG_IEEE80211R
     384         651 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
     385          80 :                 return WPA_KEY_MGMT_FT_IEEE8021X;
     386         571 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
     387         259 :                 return WPA_KEY_MGMT_FT_PSK;
     388             : #endif /* CONFIG_IEEE80211R */
     389             : #ifdef CONFIG_IEEE80211W
     390         312 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
     391          14 :                 return WPA_KEY_MGMT_IEEE8021X_SHA256;
     392         298 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
     393          56 :                 return WPA_KEY_MGMT_PSK_SHA256;
     394             : #endif /* CONFIG_IEEE80211W */
     395             : #ifdef CONFIG_SAE
     396         242 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
     397         128 :                 return WPA_KEY_MGMT_SAE;
     398         114 :         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
     399          72 :                 return WPA_KEY_MGMT_FT_SAE;
     400             : #endif /* CONFIG_SAE */
     401          42 :         return 0;
     402             : }
     403             : 
     404             : 
     405        2998 : static int wpa_cipher_valid_group(int cipher)
     406             : {
     407        6039 :         return wpa_cipher_valid_pairwise(cipher) ||
     408          43 :                 cipher == WPA_CIPHER_WEP104 ||
     409        3041 :                 cipher == WPA_CIPHER_WEP40 ||
     410             :                 cipher == WPA_CIPHER_GTK_NOT_USED;
     411             : }
     412             : 
     413             : 
     414             : #ifdef CONFIG_IEEE80211W
     415        1809 : int wpa_cipher_valid_mgmt_group(int cipher)
     416             : {
     417        3062 :         return cipher == WPA_CIPHER_AES_128_CMAC ||
     418        1253 :                 cipher == WPA_CIPHER_BIP_GMAC_128 ||
     419        3062 :                 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        3006 : 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        3006 :         os_memset(data, 0, sizeof(*data));
     441        3006 :         data->proto = WPA_PROTO_RSN;
     442        3006 :         data->pairwise_cipher = WPA_CIPHER_CCMP;
     443        3006 :         data->group_cipher = WPA_CIPHER_CCMP;
     444        3006 :         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
     445        3006 :         data->capabilities = 0;
     446        3006 :         data->pmkid = NULL;
     447        3006 :         data->num_pmkid = 0;
     448             : #ifdef CONFIG_IEEE80211W
     449        3006 :         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        3006 :         if (rsn_ie_len == 0) {
     455             :                 /* No RSN IE - fail silently */
     456           1 :                 return -1;
     457             :         }
     458             : 
     459        3005 :         if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
     460           1 :                 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
     461             :                            __func__, (unsigned long) rsn_ie_len);
     462           1 :                 return -1;
     463             :         }
     464             : 
     465        3004 :         hdr = (const struct rsn_ie_hdr *) rsn_ie;
     466             : 
     467        6008 :         if (hdr->elem_id != WLAN_EID_RSN ||
     468        6007 :             hdr->len != rsn_ie_len - 2 ||
     469        3003 :             WPA_GET_LE16(hdr->version) != RSN_VERSION) {
     470           4 :                 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
     471             :                            __func__);
     472           4 :                 return -2;
     473             :         }
     474             : 
     475        3000 :         pos = (const u8 *) (hdr + 1);
     476        3000 :         left = rsn_ie_len - sizeof(*hdr);
     477             : 
     478        3000 :         if (left >= RSN_SELECTOR_LEN) {
     479        2998 :                 data->group_cipher = rsn_selector_to_bitfield(pos);
     480        2998 :                 if (!wpa_cipher_valid_group(data->group_cipher)) {
     481           1 :                         wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x",
     482             :                                    __func__, data->group_cipher);
     483           1 :                         return -1;
     484             :                 }
     485        2997 :                 pos += RSN_SELECTOR_LEN;
     486        2997 :                 left -= RSN_SELECTOR_LEN;
     487           2 :         } else if (left > 0) {
     488           1 :                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
     489             :                            __func__, left);
     490           1 :                 return -3;
     491             :         }
     492             : 
     493        2998 :         if (left >= 2) {
     494        2995 :                 data->pairwise_cipher = 0;
     495        2995 :                 count = WPA_GET_LE16(pos);
     496        2995 :                 pos += 2;
     497        2995 :                 left -= 2;
     498        2995 :                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
     499           3 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
     500             :                                    "count %u left %u", __func__, count, left);
     501           3 :                         return -4;
     502             :                 }
     503        6029 :                 for (i = 0; i < count; i++) {
     504        3037 :                         data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
     505        3037 :                         pos += RSN_SELECTOR_LEN;
     506        3037 :                         left -= RSN_SELECTOR_LEN;
     507             :                 }
     508             : #ifdef CONFIG_IEEE80211W
     509        2992 :                 if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
     510           1 :                         wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
     511             :                                    "pairwise cipher", __func__);
     512           1 :                         return -1;
     513             :                 }
     514             : #endif /* CONFIG_IEEE80211W */
     515           3 :         } else if (left == 1) {
     516           1 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
     517             :                            __func__);
     518           1 :                 return -5;
     519             :         }
     520             : 
     521        2993 :         if (left >= 2) {
     522        2984 :                 data->key_mgmt = 0;
     523        2984 :                 count = WPA_GET_LE16(pos);
     524        2984 :                 pos += 2;
     525        2984 :                 left -= 2;
     526        2984 :                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
     527           2 :                         wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
     528             :                                    "count %u left %u", __func__, count, left);
     529           2 :                         return -6;
     530             :                 }
     531        6040 :                 for (i = 0; i < count; i++) {
     532        3058 :                         data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
     533        3058 :                         pos += RSN_SELECTOR_LEN;
     534        3058 :                         left -= RSN_SELECTOR_LEN;
     535             :                 }
     536           9 :         } else if (left == 1) {
     537           1 :                 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
     538             :                            __func__);
     539           1 :                 return -7;
     540             :         }
     541             : 
     542        2990 :         if (left >= 2) {
     543        2979 :                 data->capabilities = WPA_GET_LE16(pos);
     544        2979 :                 pos += 2;
     545        2979 :                 left -= 2;
     546             :         }
     547             : 
     548        2990 :         if (left >= 2) {
     549         655 :                 data->num_pmkid = WPA_GET_LE16(pos);
     550         655 :                 pos += 2;
     551         655 :                 left -= 2;
     552         655 :                 if (left < (int) data->num_pmkid * PMKID_LEN) {
     553           1 :                         wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
     554             :                                    "(num_pmkid=%lu left=%d)",
     555             :                                    __func__, (unsigned long) data->num_pmkid,
     556             :                                    left);
     557           1 :                         data->num_pmkid = 0;
     558           1 :                         return -9;
     559             :                 } else {
     560         654 :                         data->pmkid = pos;
     561         654 :                         pos += data->num_pmkid * PMKID_LEN;
     562         654 :                         left -= data->num_pmkid * PMKID_LEN;
     563             :                 }
     564             :         }
     565             : 
     566             : #ifdef CONFIG_IEEE80211W
     567        2989 :         if (left >= 4) {
     568         471 :                 data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
     569         471 :                 if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
     570           1 :                         wpa_printf(MSG_DEBUG, "%s: Unsupported management "
     571             :                                    "group cipher 0x%x", __func__,
     572             :                                    data->mgmt_group_cipher);
     573           1 :                         return -10;
     574             :                 }
     575         470 :                 pos += RSN_SELECTOR_LEN;
     576         470 :                 left -= RSN_SELECTOR_LEN;
     577             :         }
     578             : #endif /* CONFIG_IEEE80211W */
     579             : 
     580        2988 :         if (left > 0) {
     581           2 :                 wpa_hexdump(MSG_DEBUG,
     582             :                             "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
     583             :                             pos, left);
     584             :         }
     585             : 
     586        2988 :         return 0;
     587             : }
     588             : 
     589             : 
     590         106 : static int wpa_selector_to_bitfield(const u8 *s)
     591             : {
     592         106 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
     593           0 :                 return WPA_CIPHER_NONE;
     594         106 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
     595           0 :                 return WPA_CIPHER_WEP40;
     596         106 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
     597          90 :                 return WPA_CIPHER_TKIP;
     598          16 :         if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
     599          16 :                 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          48 : static int wpa_key_mgmt_to_bitfield(const u8 *s)
     607             : {
     608          48 :         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
     609           3 :                 return WPA_KEY_MGMT_IEEE8021X;
     610          45 :         if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
     611          45 :                 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          48 : 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          48 :         os_memset(data, 0, sizeof(*data));
     627          48 :         data->proto = WPA_PROTO_WPA;
     628          48 :         data->pairwise_cipher = WPA_CIPHER_TKIP;
     629          48 :         data->group_cipher = WPA_CIPHER_TKIP;
     630          48 :         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
     631          48 :         data->capabilities = 0;
     632          48 :         data->pmkid = NULL;
     633          48 :         data->num_pmkid = 0;
     634          48 :         data->mgmt_group_cipher = 0;
     635             : 
     636          48 :         if (wpa_ie_len == 0) {
     637             :                 /* No WPA IE - fail silently */
     638           0 :                 return -1;
     639             :         }
     640             : 
     641          48 :         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          48 :         hdr = (const struct wpa_ie_hdr *) wpa_ie;
     648             : 
     649          96 :         if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
     650          96 :             hdr->len != wpa_ie_len - 2 ||
     651          96 :             RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
     652          48 :             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          48 :         pos = (const u8 *) (hdr + 1);
     659          48 :         left = wpa_ie_len - sizeof(*hdr);
     660             : 
     661          48 :         if (left >= WPA_SELECTOR_LEN) {
     662          48 :                 data->group_cipher = wpa_selector_to_bitfield(pos);
     663          48 :                 pos += WPA_SELECTOR_LEN;
     664          48 :                 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          48 :         if (left >= 2) {
     672          48 :                 data->pairwise_cipher = 0;
     673          48 :                 count = WPA_GET_LE16(pos);
     674          48 :                 pos += 2;
     675          48 :                 left -= 2;
     676          48 :                 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         106 :                 for (i = 0; i < count; i++) {
     682          58 :                         data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
     683          58 :                         pos += WPA_SELECTOR_LEN;
     684          58 :                         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          48 :         if (left >= 2) {
     693          48 :                 data->key_mgmt = 0;
     694          48 :                 count = WPA_GET_LE16(pos);
     695          48 :                 pos += 2;
     696          48 :                 left -= 2;
     697          48 :                 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          96 :                 for (i = 0; i < count; i++) {
     703          48 :                         data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
     704          48 :                         pos += WPA_SELECTOR_LEN;
     705          48 :                         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          48 :         if (left >= 2) {
     714           0 :                 data->capabilities = WPA_GET_LE16(pos);
     715           0 :                 pos += 2;
     716           0 :                 left -= 2;
     717             :         }
     718             : 
     719          48 :         if (left > 0) {
     720           0 :                 wpa_hexdump(MSG_DEBUG,
     721             :                             "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
     722             :                             pos, left);
     723             :         }
     724             : 
     725          48 :         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          32 : 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          32 :         if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
     756          32 :                 return;
     757          32 :         pos = buf;
     758          32 :         *pos++ = ssid_len;
     759          32 :         os_memcpy(pos, ssid, ssid_len);
     760          32 :         pos += ssid_len;
     761          32 :         os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
     762          32 :         pos += MOBILITY_DOMAIN_ID_LEN;
     763          32 :         *pos++ = r0kh_id_len;
     764          32 :         os_memcpy(pos, r0kh_id, r0kh_id_len);
     765          32 :         pos += r0kh_id_len;
     766          32 :         os_memcpy(pos, s0kh_id, ETH_ALEN);
     767          32 :         pos += ETH_ALEN;
     768             : 
     769          32 :         sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
     770             :                    r0_key_data, sizeof(r0_key_data));
     771          32 :         os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
     772             : 
     773             :         /*
     774             :          * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
     775             :          */
     776          32 :         addr[0] = (const u8 *) "FT-R0N";
     777          32 :         len[0] = 6;
     778          32 :         addr[1] = r0_key_data + PMK_LEN;
     779          32 :         len[1] = 16;
     780             : 
     781          32 :         sha256_vector(2, addr, len, hash);
     782          32 :         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          91 : 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          91 :         addr[0] = (const u8 *) "FT-R1N";
     803          91 :         len[0] = 6;
     804          91 :         addr[1] = pmk_r0_name;
     805          91 :         len[1] = WPA_PMK_NAME_LEN;
     806          91 :         addr[2] = r1kh_id;
     807          91 :         len[2] = FT_R1KH_ID_LEN;
     808          91 :         addr[3] = s1kh_id;
     809          91 :         len[3] = ETH_ALEN;
     810             : 
     811          91 :         sha256_vector(4, addr, len, hash);
     812          91 :         os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
     813          91 : }
     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          64 : 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          64 :         pos = buf;
     830          64 :         os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
     831          64 :         pos += FT_R1KH_ID_LEN;
     832          64 :         os_memcpy(pos, s1kh_id, ETH_ALEN);
     833          64 :         pos += ETH_ALEN;
     834             : 
     835          64 :         sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
     836             : 
     837          64 :         wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
     838          64 : }
     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          72 : 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          72 :         pos = buf;
     861          72 :         os_memcpy(pos, snonce, WPA_NONCE_LEN);
     862          72 :         pos += WPA_NONCE_LEN;
     863          72 :         os_memcpy(pos, anonce, WPA_NONCE_LEN);
     864          72 :         pos += WPA_NONCE_LEN;
     865          72 :         os_memcpy(pos, bssid, ETH_ALEN);
     866          72 :         pos += ETH_ALEN;
     867          72 :         os_memcpy(pos, sta_addr, ETH_ALEN);
     868          72 :         pos += ETH_ALEN;
     869             : 
     870          72 :         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          72 :         addr[0] = pmk_r1_name;
     877          72 :         len[0] = WPA_PMK_NAME_LEN;
     878          72 :         addr[1] = (const u8 *) "FT-PTKN";
     879          72 :         len[1] = 7;
     880          72 :         addr[2] = snonce;
     881          72 :         len[2] = WPA_NONCE_LEN;
     882          72 :         addr[3] = anonce;
     883          72 :         len[3] = WPA_NONCE_LEN;
     884          72 :         addr[4] = bssid;
     885          72 :         len[4] = ETH_ALEN;
     886          72 :         addr[5] = sta_addr;
     887          72 :         len[5] = ETH_ALEN;
     888             : 
     889          72 :         sha256_vector(6, addr, len, hash);
     890          72 :         os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
     891          72 : }
     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         821 : void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
     909             :                u8 *pmkid, int use_sha256)
     910             : {
     911         821 :         char *title = "PMK Name";
     912             :         const u8 *addr[3];
     913         821 :         const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
     914             :         unsigned char hash[SHA256_MAC_LEN];
     915             : 
     916         821 :         addr[0] = (u8 *) title;
     917         821 :         addr[1] = aa;
     918         821 :         addr[2] = spa;
     919             : 
     920             : #ifdef CONFIG_IEEE80211W
     921         821 :         if (use_sha256)
     922           9 :                 hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
     923             :         else
     924             : #endif /* CONFIG_IEEE80211W */
     925         812 :                 hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
     926         821 :         os_memcpy(pmkid, hash, PMKID_LEN);
     927         821 : }
     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        3685 : const char * wpa_cipher_txt(int cipher)
     936             : {
     937        3685 :         switch (cipher) {
     938             :         case WPA_CIPHER_NONE:
     939         196 :                 return "NONE";
     940             :         case WPA_CIPHER_WEP40:
     941          12 :                 return "WEP-40";
     942             :         case WPA_CIPHER_WEP104:
     943           0 :                 return "WEP-104";
     944             :         case WPA_CIPHER_TKIP:
     945         158 :                 return "TKIP";
     946             :         case WPA_CIPHER_CCMP:
     947        3314 :                 return "CCMP";
     948             :         case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
     949           1 :                 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           4 :                 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         501 : const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
     971             : {
     972         501 :         switch (key_mgmt) {
     973             :         case WPA_KEY_MGMT_IEEE8021X:
     974         185 :                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
     975           0 :                         return "WPA2+WPA/IEEE 802.1X/EAP";
     976         185 :                 return proto == WPA_PROTO_RSN ?
     977         185 :                         "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
     978             :         case WPA_KEY_MGMT_PSK:
     979         149 :                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
     980           0 :                         return "WPA2-PSK+WPA-PSK";
     981         149 :                 return proto == WPA_PROTO_RSN ?
     982         149 :                         "WPA2-PSK" : "WPA-PSK";
     983             :         case WPA_KEY_MGMT_NONE:
     984         103 :                 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           6 :                 return "FT-EAP";
     990             :         case WPA_KEY_MGMT_FT_PSK:
     991          22 :                 return "FT-PSK";
     992             : #endif /* CONFIG_IEEE80211R */
     993             : #ifdef CONFIG_IEEE80211W
     994             :         case WPA_KEY_MGMT_IEEE8021X_SHA256:
     995           2 :                 return "WPA2-EAP-SHA256";
     996             :         case WPA_KEY_MGMT_PSK_SHA256:
     997          14 :                 return "WPA2-PSK-SHA256";
     998             : #endif /* CONFIG_IEEE80211W */
     999             :         default:
    1000          20 :                 return "UNKNOWN";
    1001             :         }
    1002             : }
    1003             : 
    1004             : 
    1005        1260 : int wpa_compare_rsn_ie(int ft_initial_assoc,
    1006             :                        const u8 *ie1, size_t ie1len,
    1007             :                        const u8 *ie2, size_t ie2len)
    1008             : {
    1009        1260 :         if (ie1 == NULL || ie2 == NULL)
    1010           0 :                 return -1;
    1011             : 
    1012        1260 :         if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
    1013        1228 :                 return 0; /* identical IEs */
    1014             : 
    1015             : #ifdef CONFIG_IEEE80211R
    1016          32 :         if (ft_initial_assoc) {
    1017             :                 struct wpa_ie_data ie1d, ie2d;
    1018             :                 /*
    1019             :                  * The PMKID-List in RSN IE is different between Beacon/Probe
    1020             :                  * Response/(Re)Association Request frames and EAPOL-Key
    1021             :                  * messages in FT initial mobility domain association. Allow
    1022             :                  * for this, but verify that other parts of the RSN IEs are
    1023             :                  * identical.
    1024             :                  */
    1025          64 :                 if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
    1026          32 :                     wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
    1027          32 :                         return -1;
    1028          64 :                 if (ie1d.proto == ie2d.proto &&
    1029          64 :                     ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
    1030          64 :                     ie1d.group_cipher == ie2d.group_cipher &&
    1031          64 :                     ie1d.key_mgmt == ie2d.key_mgmt &&
    1032          64 :                     ie1d.capabilities == ie2d.capabilities &&
    1033          32 :                     ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
    1034          32 :                         return 0;
    1035             :         }
    1036             : #endif /* CONFIG_IEEE80211R */
    1037             : 
    1038           0 :         return -1;
    1039             : }
    1040             : 
    1041             : 
    1042             : #ifdef CONFIG_IEEE80211R
    1043          32 : int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
    1044             : {
    1045             :         u8 *start, *end, *rpos, *rend;
    1046          32 :         int added = 0;
    1047             : 
    1048          32 :         start = ies;
    1049          32 :         end = ies + ies_len;
    1050             : 
    1051          64 :         while (start < end) {
    1052          32 :                 if (*start == WLAN_EID_RSN)
    1053          32 :                         break;
    1054           0 :                 start += 2 + start[1];
    1055             :         }
    1056          32 :         if (start >= end) {
    1057           0 :                 wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
    1058             :                            "IEs data");
    1059           0 :                 return -1;
    1060             :         }
    1061          32 :         wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
    1062          32 :                     start, 2 + start[1]);
    1063             : 
    1064             :         /* Find start of PMKID-Count */
    1065          32 :         rpos = start + 2;
    1066          32 :         rend = rpos + start[1];
    1067             : 
    1068             :         /* Skip Version and Group Data Cipher Suite */
    1069          32 :         rpos += 2 + 4;
    1070             :         /* Skip Pairwise Cipher Suite Count and List */
    1071          32 :         rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
    1072             :         /* Skip AKM Suite Count and List */
    1073          32 :         rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
    1074             : 
    1075          32 :         if (rpos == rend) {
    1076             :                 /* Add RSN Capabilities */
    1077           0 :                 os_memmove(rpos + 2, rpos, end - rpos);
    1078           0 :                 *rpos++ = 0;
    1079           0 :                 *rpos++ = 0;
    1080             :         } else {
    1081             :                 /* Skip RSN Capabilities */
    1082          32 :                 rpos += 2;
    1083          32 :                 if (rpos > rend) {
    1084           0 :                         wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
    1085             :                                    "IEs data");
    1086           0 :                         return -1;
    1087             :                 }
    1088             :         }
    1089             : 
    1090          32 :         if (rpos == rend) {
    1091             :                 /* No PMKID-Count field included; add it */
    1092          23 :                 os_memmove(rpos + 2 + PMKID_LEN, rpos, end - rpos);
    1093          23 :                 WPA_PUT_LE16(rpos, 1);
    1094          23 :                 rpos += 2;
    1095          23 :                 os_memcpy(rpos, pmkid, PMKID_LEN);
    1096          23 :                 added += 2 + PMKID_LEN;
    1097          23 :                 start[1] += 2 + PMKID_LEN;
    1098             :         } else {
    1099             :                 /* PMKID-Count was included; use it */
    1100           9 :                 if (WPA_GET_LE16(rpos) != 0) {
    1101           0 :                         wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
    1102             :                                    "in RSN IE in EAPOL-Key data");
    1103           0 :                         return -1;
    1104             :                 }
    1105           9 :                 WPA_PUT_LE16(rpos, 1);
    1106           9 :                 rpos += 2;
    1107           9 :                 os_memmove(rpos + PMKID_LEN, rpos, end - rpos);
    1108           9 :                 os_memcpy(rpos, pmkid, PMKID_LEN);
    1109           9 :                 added += PMKID_LEN;
    1110           9 :                 start[1] += PMKID_LEN;
    1111             :         }
    1112             : 
    1113          32 :         wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
    1114          32 :                     "(PMKID inserted)", start, 2 + start[1]);
    1115             : 
    1116          32 :         return added;
    1117             : }
    1118             : #endif /* CONFIG_IEEE80211R */
    1119             : 
    1120             : 
    1121        6875 : int wpa_cipher_key_len(int cipher)
    1122             : {
    1123        6875 :         switch (cipher) {
    1124             :         case WPA_CIPHER_CCMP_256:
    1125             :         case WPA_CIPHER_GCMP_256:
    1126             :         case WPA_CIPHER_BIP_GMAC_256:
    1127             :         case WPA_CIPHER_BIP_CMAC_256:
    1128           0 :                 return 32;
    1129             :         case WPA_CIPHER_CCMP:
    1130             :         case WPA_CIPHER_GCMP:
    1131             :         case WPA_CIPHER_AES_128_CMAC:
    1132             :         case WPA_CIPHER_BIP_GMAC_128:
    1133        6681 :                 return 16;
    1134             :         case WPA_CIPHER_TKIP:
    1135         183 :                 return 32;
    1136             :         case WPA_CIPHER_WEP104:
    1137           0 :                 return 13;
    1138             :         case WPA_CIPHER_WEP40:
    1139           0 :                 return 5;
    1140             :         }
    1141             : 
    1142          11 :         return 0;
    1143             : }
    1144             : 
    1145             : 
    1146        1274 : int wpa_cipher_rsc_len(int cipher)
    1147             : {
    1148        1274 :         switch (cipher) {
    1149             :         case WPA_CIPHER_CCMP_256:
    1150             :         case WPA_CIPHER_GCMP_256:
    1151             :         case WPA_CIPHER_CCMP:
    1152             :         case WPA_CIPHER_GCMP:
    1153             :         case WPA_CIPHER_TKIP:
    1154        1274 :                 return 6;
    1155             :         case WPA_CIPHER_WEP104:
    1156             :         case WPA_CIPHER_WEP40:
    1157           0 :                 return 0;
    1158             :         }
    1159             : 
    1160           0 :         return 0;
    1161             : }
    1162             : 
    1163             : 
    1164        3158 : int wpa_cipher_to_alg(int cipher)
    1165             : {
    1166        3158 :         switch (cipher) {
    1167             :         case WPA_CIPHER_CCMP_256:
    1168           0 :                 return WPA_ALG_CCMP_256;
    1169             :         case WPA_CIPHER_GCMP_256:
    1170           0 :                 return WPA_ALG_GCMP_256;
    1171             :         case WPA_CIPHER_CCMP:
    1172        2807 :                 return WPA_ALG_CCMP;
    1173             :         case WPA_CIPHER_GCMP:
    1174           0 :                 return WPA_ALG_GCMP;
    1175             :         case WPA_CIPHER_TKIP:
    1176         115 :                 return WPA_ALG_TKIP;
    1177             :         case WPA_CIPHER_WEP104:
    1178             :         case WPA_CIPHER_WEP40:
    1179           0 :                 return WPA_ALG_WEP;
    1180             :         case WPA_CIPHER_AES_128_CMAC:
    1181         236 :                 return WPA_ALG_IGTK;
    1182             :         case WPA_CIPHER_BIP_GMAC_128:
    1183           0 :                 return WPA_ALG_BIP_GMAC_128;
    1184             :         case WPA_CIPHER_BIP_GMAC_256:
    1185           0 :                 return WPA_ALG_BIP_GMAC_256;
    1186             :         case WPA_CIPHER_BIP_CMAC_256:
    1187           0 :                 return WPA_ALG_BIP_CMAC_256;
    1188             :         }
    1189           0 :         return WPA_ALG_NONE;
    1190             : }
    1191             : 
    1192             : 
    1193        4524 : int wpa_cipher_valid_pairwise(int cipher)
    1194             : {
    1195        9048 :         return cipher == WPA_CIPHER_CCMP_256 ||
    1196        4524 :                 cipher == WPA_CIPHER_GCMP_256 ||
    1197         190 :                 cipher == WPA_CIPHER_CCMP ||
    1198        4714 :                 cipher == WPA_CIPHER_GCMP ||
    1199             :                 cipher == WPA_CIPHER_TKIP;
    1200             : }
    1201             : 
    1202             : 
    1203        3688 : u32 wpa_cipher_to_suite(int proto, int cipher)
    1204             : {
    1205        3688 :         if (cipher & WPA_CIPHER_CCMP_256)
    1206           0 :                 return RSN_CIPHER_SUITE_CCMP_256;
    1207        3688 :         if (cipher & WPA_CIPHER_GCMP_256)
    1208           0 :                 return RSN_CIPHER_SUITE_GCMP_256;
    1209        3688 :         if (cipher & WPA_CIPHER_CCMP)
    1210        3466 :                 return (proto == WPA_PROTO_RSN ?
    1211        3466 :                         RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
    1212         222 :         if (cipher & WPA_CIPHER_GCMP)
    1213           0 :                 return RSN_CIPHER_SUITE_GCMP;
    1214         222 :         if (cipher & WPA_CIPHER_TKIP)
    1215         174 :                 return (proto == WPA_PROTO_RSN ?
    1216         174 :                         RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
    1217          48 :         if (cipher & WPA_CIPHER_WEP104)
    1218           0 :                 return (proto == WPA_PROTO_RSN ?
    1219           0 :                         RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
    1220          48 :         if (cipher & WPA_CIPHER_WEP40)
    1221           0 :                 return (proto == WPA_PROTO_RSN ?
    1222           0 :                         RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
    1223          48 :         if (cipher & WPA_CIPHER_NONE)
    1224          16 :                 return (proto == WPA_PROTO_RSN ?
    1225          16 :                         RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
    1226          32 :         if (cipher & WPA_CIPHER_GTK_NOT_USED)
    1227           2 :                 return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
    1228          30 :         if (cipher & WPA_CIPHER_AES_128_CMAC)
    1229          30 :                 return RSN_CIPHER_SUITE_AES_128_CMAC;
    1230           0 :         if (cipher & WPA_CIPHER_BIP_GMAC_128)
    1231           0 :                 return RSN_CIPHER_SUITE_BIP_GMAC_128;
    1232           0 :         if (cipher & WPA_CIPHER_BIP_GMAC_256)
    1233           0 :                 return RSN_CIPHER_SUITE_BIP_GMAC_256;
    1234           0 :         if (cipher & WPA_CIPHER_BIP_CMAC_256)
    1235           0 :                 return RSN_CIPHER_SUITE_BIP_CMAC_256;
    1236           0 :         return 0;
    1237             : }
    1238             : 
    1239             : 
    1240         546 : int rsn_cipher_put_suites(u8 *start, int ciphers)
    1241             : {
    1242         546 :         u8 *pos = start;
    1243             : 
    1244         546 :         if (ciphers & WPA_CIPHER_CCMP_256) {
    1245           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
    1246           0 :                 pos += RSN_SELECTOR_LEN;
    1247             :         }
    1248         546 :         if (ciphers & WPA_CIPHER_GCMP_256) {
    1249           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
    1250           0 :                 pos += RSN_SELECTOR_LEN;
    1251             :         }
    1252         546 :         if (ciphers & WPA_CIPHER_CCMP) {
    1253         544 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
    1254         544 :                 pos += RSN_SELECTOR_LEN;
    1255             :         }
    1256         546 :         if (ciphers & WPA_CIPHER_GCMP) {
    1257           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
    1258           0 :                 pos += RSN_SELECTOR_LEN;
    1259             :         }
    1260         546 :         if (ciphers & WPA_CIPHER_TKIP) {
    1261          16 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
    1262          16 :                 pos += RSN_SELECTOR_LEN;
    1263             :         }
    1264         546 :         if (ciphers & WPA_CIPHER_NONE) {
    1265           0 :                 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
    1266           0 :                 pos += RSN_SELECTOR_LEN;
    1267             :         }
    1268             : 
    1269         546 :         return (pos - start) / RSN_SELECTOR_LEN;
    1270             : }
    1271             : 
    1272             : 
    1273          23 : int wpa_cipher_put_suites(u8 *start, int ciphers)
    1274             : {
    1275          23 :         u8 *pos = start;
    1276             : 
    1277          23 :         if (ciphers & WPA_CIPHER_CCMP) {
    1278          12 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
    1279          12 :                 pos += WPA_SELECTOR_LEN;
    1280             :         }
    1281          23 :         if (ciphers & WPA_CIPHER_TKIP) {
    1282          22 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
    1283          22 :                 pos += WPA_SELECTOR_LEN;
    1284             :         }
    1285          23 :         if (ciphers & WPA_CIPHER_NONE) {
    1286           0 :                 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
    1287           0 :                 pos += WPA_SELECTOR_LEN;
    1288             :         }
    1289             : 
    1290          23 :         return (pos - start) / RSN_SELECTOR_LEN;
    1291             : }
    1292             : 
    1293             : 
    1294        1475 : int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
    1295             : {
    1296        1475 :         if (ciphers & WPA_CIPHER_CCMP_256)
    1297           0 :                 return WPA_CIPHER_CCMP_256;
    1298        1475 :         if (ciphers & WPA_CIPHER_GCMP_256)
    1299           0 :                 return WPA_CIPHER_GCMP_256;
    1300        1475 :         if (ciphers & WPA_CIPHER_CCMP)
    1301        1442 :                 return WPA_CIPHER_CCMP;
    1302          33 :         if (ciphers & WPA_CIPHER_GCMP)
    1303           0 :                 return WPA_CIPHER_GCMP;
    1304          33 :         if (ciphers & WPA_CIPHER_TKIP)
    1305          31 :                 return WPA_CIPHER_TKIP;
    1306           2 :         if (none_allowed && (ciphers & WPA_CIPHER_NONE))
    1307           0 :                 return WPA_CIPHER_NONE;
    1308           2 :         return -1;
    1309             : }
    1310             : 
    1311             : 
    1312         688 : int wpa_pick_group_cipher(int ciphers)
    1313             : {
    1314         688 :         if (ciphers & WPA_CIPHER_CCMP_256)
    1315           0 :                 return WPA_CIPHER_CCMP_256;
    1316         688 :         if (ciphers & WPA_CIPHER_GCMP_256)
    1317           0 :                 return WPA_CIPHER_GCMP_256;
    1318         688 :         if (ciphers & WPA_CIPHER_CCMP)
    1319         646 :                 return WPA_CIPHER_CCMP;
    1320          42 :         if (ciphers & WPA_CIPHER_GCMP)
    1321           0 :                 return WPA_CIPHER_GCMP;
    1322          42 :         if (ciphers & WPA_CIPHER_GTK_NOT_USED)
    1323           2 :                 return WPA_CIPHER_GTK_NOT_USED;
    1324          40 :         if (ciphers & WPA_CIPHER_TKIP)
    1325          40 :                 return WPA_CIPHER_TKIP;
    1326           0 :         if (ciphers & WPA_CIPHER_WEP104)
    1327           0 :                 return WPA_CIPHER_WEP104;
    1328           0 :         if (ciphers & WPA_CIPHER_WEP40)
    1329           0 :                 return WPA_CIPHER_WEP40;
    1330           0 :         return -1;
    1331             : }
    1332             : 
    1333             : 
    1334         519 : int wpa_parse_cipher(const char *value)
    1335             : {
    1336         519 :         int val = 0, last;
    1337             :         char *start, *end, *buf;
    1338             : 
    1339         519 :         buf = os_strdup(value);
    1340         519 :         if (buf == NULL)
    1341           0 :                 return -1;
    1342         519 :         start = buf;
    1343             : 
    1344        1050 :         while (*start != '\0') {
    1345        1066 :                 while (*start == ' ' || *start == '\t')
    1346           6 :                         start++;
    1347         530 :                 if (*start == '\0')
    1348           1 :                         break;
    1349         529 :                 end = start;
    1350        3214 :                 while (*end != ' ' && *end != '\t' && *end != '\0')
    1351        2156 :                         end++;
    1352         529 :                 last = *end == '\0';
    1353         529 :                 *end = '\0';
    1354         529 :                 if (os_strcmp(start, "CCMP-256") == 0)
    1355           2 :                         val |= WPA_CIPHER_CCMP_256;
    1356         527 :                 else if (os_strcmp(start, "GCMP-256") == 0)
    1357           2 :                         val |= WPA_CIPHER_GCMP_256;
    1358         525 :                 else if (os_strcmp(start, "CCMP") == 0)
    1359         474 :                         val |= WPA_CIPHER_CCMP;
    1360          51 :                 else if (os_strcmp(start, "GCMP") == 0)
    1361           2 :                         val |= WPA_CIPHER_GCMP;
    1362          49 :                 else if (os_strcmp(start, "TKIP") == 0)
    1363          36 :                         val |= WPA_CIPHER_TKIP;
    1364          13 :                 else if (os_strcmp(start, "WEP104") == 0)
    1365           3 :                         val |= WPA_CIPHER_WEP104;
    1366          10 :                 else if (os_strcmp(start, "WEP40") == 0)
    1367           4 :                         val |= WPA_CIPHER_WEP40;
    1368           6 :                 else if (os_strcmp(start, "NONE") == 0)
    1369           2 :                         val |= WPA_CIPHER_NONE;
    1370           4 :                 else if (os_strcmp(start, "GTK_NOT_USED") == 0)
    1371           2 :                         val |= WPA_CIPHER_GTK_NOT_USED;
    1372             :                 else {
    1373           2 :                         os_free(buf);
    1374           2 :                         return -1;
    1375             :                 }
    1376             : 
    1377         527 :                 if (last)
    1378         515 :                         break;
    1379          12 :                 start = end + 1;
    1380             :         }
    1381         517 :         os_free(buf);
    1382             : 
    1383         517 :         return val;
    1384             : }
    1385             : 
    1386             : 
    1387         173 : int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
    1388             : {
    1389         173 :         char *pos = start;
    1390             :         int ret;
    1391             : 
    1392         173 :         if (ciphers & WPA_CIPHER_CCMP_256) {
    1393           2 :                 ret = os_snprintf(pos, end - pos, "%sCCMP-256",
    1394             :                                   pos == start ? "" : delim);
    1395           2 :                 if (ret < 0 || ret >= end - pos)
    1396           0 :                         return -1;
    1397           2 :                 pos += ret;
    1398             :         }
    1399         173 :         if (ciphers & WPA_CIPHER_GCMP_256) {
    1400           2 :                 ret = os_snprintf(pos, end - pos, "%sGCMP-256",
    1401             :                                   pos == start ? "" : delim);
    1402           2 :                 if (ret < 0 || ret >= end - pos)
    1403           0 :                         return -1;
    1404           2 :                 pos += ret;
    1405             :         }
    1406         173 :         if (ciphers & WPA_CIPHER_CCMP) {
    1407         170 :                 ret = os_snprintf(pos, end - pos, "%sCCMP",
    1408             :                                   pos == start ? "" : delim);
    1409         170 :                 if (ret < 0 || ret >= end - pos)
    1410           0 :                         return -1;
    1411         170 :                 pos += ret;
    1412             :         }
    1413         173 :         if (ciphers & WPA_CIPHER_GCMP) {
    1414           2 :                 ret = os_snprintf(pos, end - pos, "%sGCMP",
    1415             :                                   pos == start ? "" : delim);
    1416           2 :                 if (ret < 0 || ret >= end - pos)
    1417           0 :                         return -1;
    1418           2 :                 pos += ret;
    1419             :         }
    1420         173 :         if (ciphers & WPA_CIPHER_TKIP) {
    1421          23 :                 ret = os_snprintf(pos, end - pos, "%sTKIP",
    1422             :                                   pos == start ? "" : delim);
    1423          23 :                 if (ret < 0 || ret >= end - pos)
    1424           0 :                         return -1;
    1425          23 :                 pos += ret;
    1426             :         }
    1427         173 :         if (ciphers & WPA_CIPHER_WEP104) {
    1428           1 :                 ret = os_snprintf(pos, end - pos, "%sWEP104",
    1429             :                                   pos == start ? "" : delim);
    1430           1 :                 if (ret < 0 || ret >= end - pos)
    1431           0 :                         return -1;
    1432           1 :                 pos += ret;
    1433             :         }
    1434         173 :         if (ciphers & WPA_CIPHER_WEP40) {
    1435           1 :                 ret = os_snprintf(pos, end - pos, "%sWEP40",
    1436             :                                   pos == start ? "" : delim);
    1437           1 :                 if (ret < 0 || ret >= end - pos)
    1438           0 :                         return -1;
    1439           1 :                 pos += ret;
    1440             :         }
    1441         173 :         if (ciphers & WPA_CIPHER_NONE) {
    1442           0 :                 ret = os_snprintf(pos, end - pos, "%sNONE",
    1443             :                                   pos == start ? "" : delim);
    1444           0 :                 if (ret < 0 || ret >= end - pos)
    1445           0 :                         return -1;
    1446           0 :                 pos += ret;
    1447             :         }
    1448             : 
    1449         173 :         return pos - start;
    1450             : }
    1451             : 
    1452             : 
    1453       10010 : int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
    1454             : {
    1455       10010 :         int pairwise = 0;
    1456             : 
    1457             :         /* Select group cipher based on the enabled pairwise cipher suites */
    1458       10010 :         if (wpa & 1)
    1459          71 :                 pairwise |= wpa_pairwise;
    1460       10010 :         if (wpa & 2)
    1461        5143 :                 pairwise |= rsn_pairwise;
    1462             : 
    1463       10010 :         if (pairwise & WPA_CIPHER_TKIP)
    1464          54 :                 return WPA_CIPHER_TKIP;
    1465        9956 :         if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
    1466           0 :                 return WPA_CIPHER_GCMP;
    1467        9956 :         if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
    1468             :                          WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
    1469           0 :                 return WPA_CIPHER_GCMP_256;
    1470        9956 :         if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
    1471             :                          WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
    1472           0 :                 return WPA_CIPHER_CCMP_256;
    1473        9956 :         return WPA_CIPHER_CCMP;
    1474             : }

Generated by: LCOV version 1.10