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

Generated by: LCOV version 1.10