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

Generated by: LCOV version 1.10