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 1422976643 Lines: 760 890 85.4 %
Date: 2015-02-03 Functions: 40 40 100.0 %

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

Generated by: LCOV version 1.10