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 1393793999 Lines: 591 764 77.4 %
Date: 2014-03-02 Functions: 32 32 100.0 %
Branches: 314 524 59.9 %

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

Generated by: LCOV version 1.9