LCOV - code coverage report
Current view: top level - src/rsn_supp - wpa.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 1116 1338 83.4 %
Date: 2015-03-15 Functions: 63 66 95.5 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant - WPA state machine and EAPOL-Key processing
       3             :  * Copyright (c) 2003-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/aes_wrap.h"
      13             : #include "crypto/crypto.h"
      14             : #include "crypto/random.h"
      15             : #include "common/ieee802_11_defs.h"
      16             : #include "eapol_supp/eapol_supp_sm.h"
      17             : #include "wpa.h"
      18             : #include "eloop.h"
      19             : #include "preauth.h"
      20             : #include "pmksa_cache.h"
      21             : #include "wpa_i.h"
      22             : #include "wpa_ie.h"
      23             : #include "peerkey.h"
      24             : 
      25             : 
      26             : /**
      27             :  * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
      28             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
      29             :  * @kck: Key Confirmation Key (KCK, part of PTK)
      30             :  * @kck_len: KCK length in octets
      31             :  * @ver: Version field from Key Info
      32             :  * @dest: Destination address for the frame
      33             :  * @proto: Ethertype (usually ETH_P_EAPOL)
      34             :  * @msg: EAPOL-Key message
      35             :  * @msg_len: Length of message
      36             :  * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
      37             :  */
      38        2777 : void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, size_t kck_len,
      39             :                         int ver, const u8 *dest, u16 proto,
      40             :                         u8 *msg, size_t msg_len, u8 *key_mic)
      41             : {
      42        2777 :         size_t mic_len = wpa_mic_len(sm->key_mgmt);
      43             : 
      44        2777 :         if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
      45             :                 /*
      46             :                  * Association event was not yet received; try to fetch
      47             :                  * BSSID from the driver.
      48             :                  */
      49           0 :                 if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
      50           0 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
      51             :                                 "WPA: Failed to read BSSID for "
      52             :                                 "EAPOL-Key destination address");
      53             :                 } else {
      54           0 :                         dest = sm->bssid;
      55           0 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
      56             :                                 "WPA: Use BSSID (" MACSTR
      57             :                                 ") as the destination for EAPOL-Key",
      58             :                                 MAC2STR(dest));
      59             :                 }
      60             :         }
      61        5553 :         if (key_mic &&
      62        2776 :             wpa_eapol_key_mic(kck, kck_len, sm->key_mgmt, ver, msg, msg_len,
      63             :                               key_mic)) {
      64           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
      65             :                         "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC",
      66             :                         ver, sm->key_mgmt);
      67           0 :                 goto out;
      68             :         }
      69        2777 :         wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, kck_len);
      70        2777 :         wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, mic_len);
      71        2777 :         wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
      72        2777 :         wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
      73        2777 :         eapol_sm_notify_tx_eapol_key(sm->eapol);
      74             : out:
      75        2777 :         os_free(msg);
      76        2777 : }
      77             : 
      78             : 
      79             : /**
      80             :  * wpa_sm_key_request - Send EAPOL-Key Request
      81             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
      82             :  * @error: Indicate whether this is an Michael MIC error report
      83             :  * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
      84             :  *
      85             :  * Send an EAPOL-Key Request to the current authenticator. This function is
      86             :  * used to request rekeying and it is usually called when a local Michael MIC
      87             :  * failure is detected.
      88             :  */
      89           7 : void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
      90             : {
      91             :         size_t mic_len, hdrlen, rlen;
      92             :         struct wpa_eapol_key *reply;
      93             :         struct wpa_eapol_key_192 *reply192;
      94             :         int key_info, ver;
      95             :         u8 bssid[ETH_ALEN], *rbuf, *key_mic;
      96             : 
      97          14 :         if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
      98           7 :             wpa_key_mgmt_suite_b(sm->key_mgmt))
      99           0 :                 ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
     100          14 :         else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
     101           7 :                  wpa_key_mgmt_sha256(sm->key_mgmt))
     102           1 :                 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
     103           6 :         else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
     104           1 :                 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
     105             :         else
     106           5 :                 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
     107             : 
     108           7 :         if (wpa_sm_get_bssid(sm, bssid) < 0) {
     109           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     110             :                         "Failed to read BSSID for EAPOL-Key request");
     111           0 :                 return;
     112             :         }
     113             : 
     114           7 :         mic_len = wpa_mic_len(sm->key_mgmt);
     115           7 :         hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
     116           7 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
     117             :                                   hdrlen, &rlen, (void *) &reply);
     118           7 :         if (rbuf == NULL)
     119           0 :                 return;
     120           7 :         reply192 = (struct wpa_eapol_key_192 *) reply;
     121             : 
     122          12 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
     123           5 :                        sm->proto == WPA_PROTO_OSEN) ?
     124             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
     125           7 :         key_info = WPA_KEY_INFO_REQUEST | ver;
     126           7 :         if (sm->ptk_set)
     127           7 :                 key_info |= WPA_KEY_INFO_MIC;
     128           7 :         if (error)
     129           4 :                 key_info |= WPA_KEY_INFO_ERROR;
     130           7 :         if (pairwise)
     131           5 :                 key_info |= WPA_KEY_INFO_KEY_TYPE;
     132           7 :         WPA_PUT_BE16(reply->key_info, key_info);
     133           7 :         WPA_PUT_BE16(reply->key_length, 0);
     134           7 :         os_memcpy(reply->replay_counter, sm->request_counter,
     135             :                   WPA_REPLAY_COUNTER_LEN);
     136           7 :         inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
     137             : 
     138           7 :         if (mic_len == 24)
     139           0 :                 WPA_PUT_BE16(reply192->key_data_length, 0);
     140             :         else
     141           7 :                 WPA_PUT_BE16(reply->key_data_length, 0);
     142           7 :         if (!(key_info & WPA_KEY_INFO_MIC))
     143           0 :                 key_mic = NULL;
     144             :         else
     145           7 :                 key_mic = reply192->key_mic; /* same offset in reply */
     146             : 
     147           7 :         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     148             :                 "WPA: Sending EAPOL-Key Request (error=%d "
     149             :                 "pairwise=%d ptk_set=%d len=%lu)",
     150             :                 error, pairwise, sm->ptk_set, (unsigned long) rlen);
     151           7 :         wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
     152             :                            ETH_P_EAPOL, rbuf, rlen, key_mic);
     153             : }
     154             : 
     155             : 
     156         627 : static void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm)
     157             : {
     158             : #ifdef CONFIG_IEEE80211R
     159         627 :         if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
     160           4 :                 if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len))
     161           0 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     162             :                                 "RSN: Cannot set low order 256 bits of MSK for key management offload");
     163             :         } else {
     164             : #endif /* CONFIG_IEEE80211R */
     165         623 :                 if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len))
     166           8 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     167             :                                 "RSN: Cannot set PMK for key management offload");
     168             : #ifdef CONFIG_IEEE80211R
     169             :         }
     170             : #endif /* CONFIG_IEEE80211R */
     171         627 : }
     172             : 
     173             : 
     174        1380 : static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
     175             :                                   const unsigned char *src_addr,
     176             :                                   const u8 *pmkid)
     177             : {
     178        1380 :         int abort_cached = 0;
     179             : 
     180        1380 :         if (pmkid && !sm->cur_pmksa) {
     181             :                 /* When using drivers that generate RSN IE, wpa_supplicant may
     182             :                  * not have enough time to get the association information
     183             :                  * event before receiving this 1/4 message, so try to find a
     184             :                  * matching PMKSA cache entry here. */
     185         623 :                 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
     186             :                                                 NULL);
     187         623 :                 if (sm->cur_pmksa) {
     188           4 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     189             :                                 "RSN: found matching PMKID from PMKSA cache");
     190             :                 } else {
     191         619 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     192             :                                 "RSN: no matching PMKID found");
     193         619 :                         abort_cached = 1;
     194             :                 }
     195             :         }
     196             : 
     197        1414 :         if (pmkid && sm->cur_pmksa &&
     198          34 :             os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
     199          33 :                 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
     200          33 :                 wpa_sm_set_pmk_from_pmksa(sm);
     201          66 :                 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
     202          33 :                                 sm->pmk, sm->pmk_len);
     203          33 :                 eapol_sm_notify_cached(sm->eapol);
     204             : #ifdef CONFIG_IEEE80211R
     205          33 :                 sm->xxkey_len = 0;
     206             : #endif /* CONFIG_IEEE80211R */
     207        1347 :         } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
     208             :                 int res, pmk_len;
     209         627 :                 pmk_len = PMK_LEN;
     210         627 :                 res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
     211         627 :                 if (res) {
     212             :                         /*
     213             :                          * EAP-LEAP is an exception from other EAP methods: it
     214             :                          * uses only 16-byte PMK.
     215             :                          */
     216           0 :                         res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
     217           0 :                         pmk_len = 16;
     218             :                 } else {
     219             : #ifdef CONFIG_IEEE80211R
     220             :                         u8 buf[2 * PMK_LEN];
     221         627 :                         if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
     222             :                         {
     223         627 :                                 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
     224         627 :                                 sm->xxkey_len = PMK_LEN;
     225         627 :                                 os_memset(buf, 0, sizeof(buf));
     226             :                         }
     227             : #endif /* CONFIG_IEEE80211R */
     228             :                 }
     229         627 :                 if (res == 0) {
     230         627 :                         struct rsn_pmksa_cache_entry *sa = NULL;
     231        1254 :                         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
     232         627 :                                         "machines", sm->pmk, pmk_len);
     233         627 :                         sm->pmk_len = pmk_len;
     234         627 :                         wpa_supplicant_key_mgmt_set_pmk(sm);
     235        1249 :                         if (sm->proto == WPA_PROTO_RSN &&
     236        1242 :                             !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
     237         620 :                             !wpa_key_mgmt_ft(sm->key_mgmt)) {
     238        1848 :                                 sa = pmksa_cache_add(sm->pmksa,
     239         616 :                                                      sm->pmk, pmk_len,
     240             :                                                      NULL, 0,
     241         616 :                                                      src_addr, sm->own_addr,
     242             :                                                      sm->network_ctx,
     243         616 :                                                      sm->key_mgmt);
     244             :                         }
     245        1247 :                         if (!sm->cur_pmksa && pmkid &&
     246         620 :                             pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
     247             :                         {
     248         615 :                                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     249             :                                         "RSN: the new PMK matches with the "
     250             :                                         "PMKID");
     251         615 :                                 abort_cached = 0;
     252             :                         }
     253             : 
     254         627 :                         if (!sm->cur_pmksa)
     255         627 :                                 sm->cur_pmksa = sa;
     256             :                 } else {
     257           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     258             :                                 "WPA: Failed to get master session key from "
     259             :                                 "EAPOL state machines - key handshake "
     260             :                                 "aborted");
     261           0 :                         if (sm->cur_pmksa) {
     262           0 :                                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     263             :                                         "RSN: Cancelled PMKSA caching "
     264             :                                         "attempt");
     265           0 :                                 sm->cur_pmksa = NULL;
     266           0 :                                 abort_cached = 1;
     267           0 :                         } else if (!abort_cached) {
     268           0 :                                 return -1;
     269             :                         }
     270             :                 }
     271             :         }
     272             : 
     273        1385 :         if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
     274          10 :             !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
     275           6 :             !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
     276             :         {
     277             :                 /* Send EAPOL-Start to trigger full EAP authentication. */
     278             :                 u8 *buf;
     279             :                 size_t buflen;
     280             : 
     281           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     282             :                         "RSN: no PMKSA entry found - trigger "
     283             :                         "full EAP authentication");
     284           1 :                 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
     285             :                                          NULL, 0, &buflen, NULL);
     286           1 :                 if (buf) {
     287           1 :                         wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
     288             :                                           buf, buflen);
     289           1 :                         os_free(buf);
     290           1 :                         return -2;
     291             :                 }
     292             : 
     293           0 :                 return -1;
     294             :         }
     295             : 
     296        1379 :         return 0;
     297             : }
     298             : 
     299             : 
     300             : /**
     301             :  * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
     302             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     303             :  * @dst: Destination address for the frame
     304             :  * @key: Pointer to the EAPOL-Key frame header
     305             :  * @ver: Version bits from EAPOL-Key Key Info
     306             :  * @nonce: Nonce value for the EAPOL-Key frame
     307             :  * @wpa_ie: WPA/RSN IE
     308             :  * @wpa_ie_len: Length of the WPA/RSN IE
     309             :  * @ptk: PTK to use for keyed hash and encryption
     310             :  * Returns: 0 on success, -1 on failure
     311             :  */
     312        1380 : int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
     313             :                                const struct wpa_eapol_key *key,
     314             :                                int ver, const u8 *nonce,
     315             :                                const u8 *wpa_ie, size_t wpa_ie_len,
     316             :                                struct wpa_ptk *ptk)
     317             : {
     318             :         size_t mic_len, hdrlen, rlen;
     319             :         struct wpa_eapol_key *reply;
     320             :         struct wpa_eapol_key_192 *reply192;
     321             :         u8 *rbuf, *key_mic;
     322        1380 :         u8 *rsn_ie_buf = NULL;
     323             : 
     324        1380 :         if (wpa_ie == NULL) {
     325           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
     326             :                         "cannot generate msg 2/4");
     327           0 :                 return -1;
     328             :         }
     329             : 
     330             : #ifdef CONFIG_IEEE80211R
     331        1380 :         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
     332             :                 int res;
     333             : 
     334             :                 /*
     335             :                  * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
     336             :                  * FTIE from (Re)Association Response.
     337             :                  */
     338          25 :                 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
     339          25 :                                        sm->assoc_resp_ies_len);
     340          25 :                 if (rsn_ie_buf == NULL)
     341           0 :                         return -1;
     342          25 :                 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
     343          25 :                 res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len,
     344          25 :                                        sm->pmk_r1_name);
     345          25 :                 if (res < 0) {
     346           0 :                         os_free(rsn_ie_buf);
     347           0 :                         return -1;
     348             :                 }
     349          25 :                 wpa_ie_len += res;
     350             : 
     351          25 :                 if (sm->assoc_resp_ies) {
     352          25 :                         os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
     353             :                                   sm->assoc_resp_ies_len);
     354          25 :                         wpa_ie_len += sm->assoc_resp_ies_len;
     355             :                 }
     356             : 
     357          25 :                 wpa_ie = rsn_ie_buf;
     358             :         }
     359             : #endif /* CONFIG_IEEE80211R */
     360             : 
     361        1380 :         wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
     362             : 
     363        1380 :         mic_len = wpa_mic_len(sm->key_mgmt);
     364        1380 :         hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
     365        1380 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
     366             :                                   NULL, hdrlen + wpa_ie_len,
     367             :                                   &rlen, (void *) &reply);
     368        1380 :         if (rbuf == NULL) {
     369           0 :                 os_free(rsn_ie_buf);
     370           0 :                 return -1;
     371             :         }
     372        1380 :         reply192 = (struct wpa_eapol_key_192 *) reply;
     373             : 
     374        1403 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
     375          23 :                        sm->proto == WPA_PROTO_OSEN) ?
     376             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
     377        1380 :         WPA_PUT_BE16(reply->key_info,
     378             :                      ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
     379        1380 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
     380        1359 :                 WPA_PUT_BE16(reply->key_length, 0);
     381             :         else
     382          21 :                 os_memcpy(reply->key_length, key->key_length, 2);
     383        1380 :         os_memcpy(reply->replay_counter, key->replay_counter,
     384             :                   WPA_REPLAY_COUNTER_LEN);
     385        1380 :         wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
     386             :                     WPA_REPLAY_COUNTER_LEN);
     387             : 
     388        1380 :         key_mic = reply192->key_mic; /* same offset for reply and reply192 */
     389        1380 :         if (mic_len == 24) {
     390           2 :                 WPA_PUT_BE16(reply192->key_data_length, wpa_ie_len);
     391           2 :                 os_memcpy(reply192 + 1, wpa_ie, wpa_ie_len);
     392             :         } else {
     393        1378 :                 WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
     394        1378 :                 os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
     395             :         }
     396        1380 :         os_free(rsn_ie_buf);
     397             : 
     398        1380 :         os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
     399             : 
     400        1380 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
     401        1380 :         wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
     402             :                            rbuf, rlen, key_mic);
     403             : 
     404        1380 :         return 0;
     405             : }
     406             : 
     407             : 
     408        1379 : static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
     409             :                           const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
     410             : {
     411             : #ifdef CONFIG_IEEE80211R
     412        1379 :         if (wpa_key_mgmt_ft(sm->key_mgmt))
     413          25 :                 return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
     414             : #endif /* CONFIG_IEEE80211R */
     415             : 
     416        4062 :         return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
     417        1354 :                               sm->own_addr, sm->bssid, sm->snonce,
     418        2708 :                               key->key_nonce, ptk, sm->key_mgmt,
     419        1354 :                               sm->pairwise_cipher);
     420             : }
     421             : 
     422             : 
     423        1381 : static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
     424             :                                           const unsigned char *src_addr,
     425             :                                           const struct wpa_eapol_key *key,
     426             :                                           u16 ver, const u8 *key_data,
     427             :                                           size_t key_data_len)
     428             : {
     429             :         struct wpa_eapol_ie_parse ie;
     430             :         struct wpa_ptk *ptk;
     431             :         int res;
     432        1381 :         u8 *kde, *kde_buf = NULL;
     433             :         size_t kde_len;
     434             : 
     435        1381 :         if (wpa_sm_get_network_ctx(sm) == NULL) {
     436           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
     437             :                         "found (msg 1 of 4)");
     438           0 :                 return;
     439             :         }
     440             : 
     441        1381 :         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
     442        1381 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
     443             :                 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
     444             : 
     445        1381 :         os_memset(&ie, 0, sizeof(ie));
     446             : 
     447        1381 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
     448             :                 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
     449        1360 :                 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
     450             :                             key_data, key_data_len);
     451        1360 :                 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
     452           1 :                         goto failed;
     453        1359 :                 if (ie.pmkid) {
     454         653 :                         wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
     455         653 :                                     "Authenticator", ie.pmkid, PMKID_LEN);
     456             :                 }
     457             :         }
     458             : 
     459        1380 :         res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
     460        1380 :         if (res == -2) {
     461           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
     462             :                         "msg 1/4 - requesting full EAP authentication");
     463           1 :                 return;
     464             :         }
     465        1379 :         if (res)
     466           0 :                 goto failed;
     467             : 
     468        1379 :         if (sm->renew_snonce) {
     469        1362 :                 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
     470           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     471             :                                 "WPA: Failed to get random data for SNonce");
     472           0 :                         goto failed;
     473             :                 }
     474        1362 :                 sm->renew_snonce = 0;
     475        1362 :                 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
     476        1362 :                             sm->snonce, WPA_NONCE_LEN);
     477             :         }
     478             : 
     479             :         /* Calculate PTK which will be stored as a temporary PTK until it has
     480             :          * been verified when processing message 3/4. */
     481        1379 :         ptk = &sm->tptk;
     482        1379 :         wpa_derive_ptk(sm, src_addr, key, ptk);
     483        1379 :         if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
     484             :                 u8 buf[8];
     485             :                 /* Supplicant: swap tx/rx Mic keys */
     486          22 :                 os_memcpy(buf, &ptk->tk[16], 8);
     487          22 :                 os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
     488          22 :                 os_memcpy(&ptk->tk[24], buf, 8);
     489          22 :                 os_memset(buf, 0, sizeof(buf));
     490             :         }
     491        1379 :         sm->tptk_set = 1;
     492             : 
     493        1379 :         kde = sm->assoc_wpa_ie;
     494        1379 :         kde_len = sm->assoc_wpa_ie_len;
     495             : 
     496             : #ifdef CONFIG_P2P
     497        1379 :         if (sm->p2p) {
     498         206 :                 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
     499         206 :                 if (kde_buf) {
     500             :                         u8 *pos;
     501         206 :                         wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
     502             :                                    "into EAPOL-Key 2/4");
     503         206 :                         os_memcpy(kde_buf, kde, kde_len);
     504         206 :                         kde = kde_buf;
     505         206 :                         pos = kde + kde_len;
     506         206 :                         *pos++ = WLAN_EID_VENDOR_SPECIFIC;
     507         206 :                         *pos++ = RSN_SELECTOR_LEN + 1;
     508         206 :                         RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
     509         206 :                         pos += RSN_SELECTOR_LEN;
     510         206 :                         *pos++ = 0x01;
     511         206 :                         kde_len = pos - kde;
     512             :                 }
     513             :         }
     514             : #endif /* CONFIG_P2P */
     515             : 
     516        1379 :         if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
     517             :                                        kde, kde_len, ptk))
     518           0 :                 goto failed;
     519             : 
     520        1379 :         os_free(kde_buf);
     521        1379 :         os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
     522        1379 :         return;
     523             : 
     524             : failed:
     525           1 :         os_free(kde_buf);
     526           1 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
     527             : }
     528             : 
     529             : 
     530         344 : static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
     531             : {
     532         344 :         struct wpa_sm *sm = eloop_ctx;
     533         344 :         rsn_preauth_candidate_process(sm);
     534         344 : }
     535             : 
     536             : 
     537        1567 : static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
     538             :                                             const u8 *addr, int secure)
     539             : {
     540       12536 :         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     541             :                 "WPA: Key negotiation completed with "
     542        9402 :                 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
     543        1567 :                 wpa_cipher_txt(sm->pairwise_cipher),
     544        1567 :                 wpa_cipher_txt(sm->group_cipher));
     545        1567 :         wpa_sm_cancel_auth_timeout(sm);
     546        1567 :         wpa_sm_set_state(sm, WPA_COMPLETED);
     547             : 
     548        1567 :         if (secure) {
     549        1567 :                 wpa_sm_mlme_setprotection(
     550             :                         sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
     551             :                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
     552        1567 :                 eapol_sm_notify_portValid(sm->eapol, TRUE);
     553        1567 :                 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
     554         906 :                         eapol_sm_notify_eap_success(sm->eapol, TRUE);
     555             :                 /*
     556             :                  * Start preauthentication after a short wait to avoid a
     557             :                  * possible race condition between the data receive and key
     558             :                  * configuration after the 4-Way Handshake. This increases the
     559             :                  * likelihood of the first preauth EAPOL-Start frame getting to
     560             :                  * the target AP.
     561             :                  */
     562        1567 :                 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
     563             :         }
     564             : 
     565        1567 :         if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
     566           6 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     567             :                         "RSN: Authenticator accepted "
     568             :                         "opportunistic PMKSA entry - marking it valid");
     569           6 :                 sm->cur_pmksa->opportunistic = 0;
     570             :         }
     571             : 
     572             : #ifdef CONFIG_IEEE80211R
     573        1567 :         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
     574             :                 /* Prepare for the next transition */
     575         246 :                 wpa_ft_prepare_auth_request(sm, NULL);
     576             :         }
     577             : #endif /* CONFIG_IEEE80211R */
     578        1567 : }
     579             : 
     580             : 
     581           3 : static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
     582             : {
     583           3 :         struct wpa_sm *sm = eloop_ctx;
     584           3 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
     585           3 :         wpa_sm_key_request(sm, 0, 1);
     586           3 : }
     587             : 
     588             : 
     589        1349 : static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
     590             :                                       const struct wpa_eapol_key *key)
     591             : {
     592             :         int keylen, rsclen;
     593             :         enum wpa_alg alg;
     594             :         const u8 *key_rsc;
     595        1349 :         u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
     596             : 
     597        1349 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     598             :                 "WPA: Installing PTK to the driver");
     599             : 
     600        1349 :         if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
     601           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
     602             :                         "Suite: NONE - do not use pairwise keys");
     603           0 :                 return 0;
     604             :         }
     605             : 
     606        1349 :         if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
     607           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     608             :                         "WPA: Unsupported pairwise cipher %d",
     609             :                         sm->pairwise_cipher);
     610           0 :                 return -1;
     611             :         }
     612             : 
     613        1349 :         alg = wpa_cipher_to_alg(sm->pairwise_cipher);
     614        1349 :         keylen = wpa_cipher_key_len(sm->pairwise_cipher);
     615        1349 :         rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
     616             : 
     617        1349 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
     618        1328 :                 key_rsc = null_rsc;
     619             :         } else {
     620          21 :                 key_rsc = key->key_rsc;
     621          21 :                 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
     622             :         }
     623             : 
     624        2698 :         if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
     625        1349 :                            sm->ptk.tk, keylen) < 0) {
     626           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     627             :                         "WPA: Failed to set PTK to the "
     628             :                         "driver (alg=%d keylen=%d bssid=" MACSTR ")",
     629           0 :                         alg, keylen, MAC2STR(sm->bssid));
     630           0 :                 return -1;
     631             :         }
     632             : 
     633             :         /* TK is not needed anymore in supplicant */
     634        1349 :         os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
     635             : 
     636        1349 :         if (sm->wpa_ptk_rekey) {
     637           6 :                 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
     638           6 :                 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
     639             :                                        sm, NULL);
     640             :         }
     641             : 
     642        1349 :         return 0;
     643             : }
     644             : 
     645             : 
     646        1356 : static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
     647             :                                              int group_cipher,
     648             :                                              int keylen, int maxkeylen,
     649             :                                              int *key_rsc_len,
     650             :                                              enum wpa_alg *alg)
     651             : {
     652             :         int klen;
     653             : 
     654        1356 :         *alg = wpa_cipher_to_alg(group_cipher);
     655        1356 :         if (*alg == WPA_ALG_NONE) {
     656           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     657             :                         "WPA: Unsupported Group Cipher %d",
     658             :                         group_cipher);
     659           0 :                 return -1;
     660             :         }
     661        1356 :         *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
     662             : 
     663        1356 :         klen = wpa_cipher_key_len(group_cipher);
     664        1356 :         if (keylen != klen || maxkeylen < klen) {
     665           2 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     666             :                         "WPA: Unsupported %s Group Cipher key length %d (%d)",
     667             :                         wpa_cipher_txt(group_cipher), keylen, maxkeylen);
     668           2 :                 return -1;
     669             :         }
     670        1354 :         return 0;
     671             : }
     672             : 
     673             : 
     674             : struct wpa_gtk_data {
     675             :         enum wpa_alg alg;
     676             :         int tx, key_rsc_len, keyidx;
     677             :         u8 gtk[32];
     678             :         int gtk_len;
     679             : };
     680             : 
     681             : 
     682        1355 : static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
     683             :                                       const struct wpa_gtk_data *gd,
     684             :                                       const u8 *key_rsc)
     685             : {
     686        1355 :         const u8 *_gtk = gd->gtk;
     687             :         u8 gtk_buf[32];
     688             : 
     689        1355 :         wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
     690        1355 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     691             :                 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
     692             :                 gd->keyidx, gd->tx, gd->gtk_len);
     693        1355 :         wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
     694        1355 :         if (sm->group_cipher == WPA_CIPHER_TKIP) {
     695             :                 /* Swap Tx/Rx keys for Michael MIC */
     696          50 :                 os_memcpy(gtk_buf, gd->gtk, 16);
     697          50 :                 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
     698          50 :                 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
     699          50 :                 _gtk = gtk_buf;
     700             :         }
     701        1355 :         if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
     702           0 :                 if (wpa_sm_set_key(sm, gd->alg, NULL,
     703           0 :                                    gd->keyidx, 1, key_rsc, gd->key_rsc_len,
     704           0 :                                    _gtk, gd->gtk_len) < 0) {
     705           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     706             :                                 "WPA: Failed to set GTK to the driver "
     707             :                                 "(Group only)");
     708           0 :                         os_memset(gtk_buf, 0, sizeof(gtk_buf));
     709           0 :                         return -1;
     710             :                 }
     711        2710 :         } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
     712        1355 :                                   gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
     713        1355 :                                   _gtk, gd->gtk_len) < 0) {
     714           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     715             :                         "WPA: Failed to set GTK to "
     716             :                         "the driver (alg=%d keylen=%d keyidx=%d)",
     717           0 :                         gd->alg, gd->gtk_len, gd->keyidx);
     718           0 :                 os_memset(gtk_buf, 0, sizeof(gtk_buf));
     719           0 :                 return -1;
     720             :         }
     721        1355 :         os_memset(gtk_buf, 0, sizeof(gtk_buf));
     722             : 
     723        1355 :         return 0;
     724             : }
     725             : 
     726             : 
     727        1356 : static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
     728             :                                                 int tx)
     729             : {
     730        1356 :         if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
     731             :                 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
     732             :                  * seemed to set this bit (incorrectly, since Tx is only when
     733             :                  * doing Group Key only APs) and without this workaround, the
     734             :                  * data connection does not work because wpa_supplicant
     735             :                  * configured non-zero keyidx to be used for unicast. */
     736           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     737             :                         "WPA: Tx bit set for GTK, but pairwise "
     738             :                         "keys are used - ignore Tx bit");
     739           1 :                 return 0;
     740             :         }
     741        1355 :         return tx;
     742             : }
     743             : 
     744             : 
     745        1325 : static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
     746             :                                        const struct wpa_eapol_key *key,
     747             :                                        const u8 *gtk, size_t gtk_len,
     748             :                                        int key_info)
     749             : {
     750             :         struct wpa_gtk_data gd;
     751             : 
     752             :         /*
     753             :          * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
     754             :          * GTK KDE format:
     755             :          * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
     756             :          * Reserved [bits 0-7]
     757             :          * GTK
     758             :          */
     759             : 
     760        1325 :         os_memset(&gd, 0, sizeof(gd));
     761        1325 :         wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
     762             :                         gtk, gtk_len);
     763             : 
     764        1325 :         if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
     765           1 :                 return -1;
     766             : 
     767        1324 :         gd.keyidx = gtk[0] & 0x3;
     768        1324 :         gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
     769        1324 :                                                      !!(gtk[0] & BIT(2)));
     770        1324 :         gtk += 2;
     771        1324 :         gtk_len -= 2;
     772             : 
     773        1324 :         os_memcpy(gd.gtk, gtk, gtk_len);
     774        1324 :         gd.gtk_len = gtk_len;
     775             : 
     776        2648 :         if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
     777        1324 :             (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
     778             :                                                gtk_len, gtk_len,
     779        1323 :                                                &gd.key_rsc_len, &gd.alg) ||
     780        1323 :              wpa_supplicant_install_gtk(sm, &gd, key->key_rsc))) {
     781           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     782             :                         "RSN: Failed to install GTK");
     783           1 :                 os_memset(&gd, 0, sizeof(gd));
     784           1 :                 return -1;
     785             :         }
     786        1323 :         os_memset(&gd, 0, sizeof(gd));
     787             : 
     788        1323 :         wpa_supplicant_key_neg_complete(sm, sm->bssid,
     789             :                                         key_info & WPA_KEY_INFO_SECURE);
     790        1323 :         return 0;
     791             : }
     792             : 
     793             : 
     794        1356 : static int ieee80211w_set_keys(struct wpa_sm *sm,
     795             :                                struct wpa_eapol_ie_parse *ie)
     796             : {
     797             : #ifdef CONFIG_IEEE80211W
     798        1356 :         if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
     799        1312 :                 return 0;
     800             : 
     801          44 :         if (ie->igtk) {
     802             :                 size_t len;
     803             :                 const struct wpa_igtk_kde *igtk;
     804             :                 u16 keyidx;
     805          44 :                 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
     806          44 :                 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
     807           0 :                         return -1;
     808          44 :                 igtk = (const struct wpa_igtk_kde *) ie->igtk;
     809          44 :                 keyidx = WPA_GET_LE16(igtk->keyid);
     810          44 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
     811             :                         "pn %02x%02x%02x%02x%02x%02x",
     812             :                         keyidx, MAC2STR(igtk->pn));
     813          44 :                 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
     814          44 :                                 igtk->igtk, len);
     815          44 :                 if (keyidx > 4095) {
     816           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     817             :                                 "WPA: Invalid IGTK KeyID %d", keyidx);
     818           0 :                         return -1;
     819             :                 }
     820          44 :                 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
     821             :                                    broadcast_ether_addr,
     822          44 :                                    keyidx, 0, igtk->pn, sizeof(igtk->pn),
     823          44 :                                    igtk->igtk, len) < 0) {
     824           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     825             :                                 "WPA: Failed to configure IGTK to the driver");
     826           0 :                         return -1;
     827             :                 }
     828             :         }
     829             : 
     830          44 :         return 0;
     831             : #else /* CONFIG_IEEE80211W */
     832             :         return 0;
     833             : #endif /* CONFIG_IEEE80211W */
     834             : }
     835             : 
     836             : 
     837           2 : static void wpa_report_ie_mismatch(struct wpa_sm *sm,
     838             :                                    const char *reason, const u8 *src_addr,
     839             :                                    const u8 *wpa_ie, size_t wpa_ie_len,
     840             :                                    const u8 *rsn_ie, size_t rsn_ie_len)
     841             : {
     842          12 :         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
     843          12 :                 reason, MAC2STR(src_addr));
     844             : 
     845           2 :         if (sm->ap_wpa_ie) {
     846           0 :                 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
     847           0 :                             sm->ap_wpa_ie, sm->ap_wpa_ie_len);
     848             :         }
     849           2 :         if (wpa_ie) {
     850           0 :                 if (!sm->ap_wpa_ie) {
     851           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     852             :                                 "WPA: No WPA IE in Beacon/ProbeResp");
     853             :                 }
     854           0 :                 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
     855             :                             wpa_ie, wpa_ie_len);
     856             :         }
     857             : 
     858           2 :         if (sm->ap_rsn_ie) {
     859           4 :                 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
     860           2 :                             sm->ap_rsn_ie, sm->ap_rsn_ie_len);
     861             :         }
     862           2 :         if (rsn_ie) {
     863           1 :                 if (!sm->ap_rsn_ie) {
     864           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     865             :                                 "WPA: No RSN IE in Beacon/ProbeResp");
     866             :                 }
     867           1 :                 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
     868             :                             rsn_ie, rsn_ie_len);
     869             :         }
     870             : 
     871           2 :         wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
     872           2 : }
     873             : 
     874             : 
     875             : #ifdef CONFIG_IEEE80211R
     876             : 
     877          25 : static int ft_validate_mdie(struct wpa_sm *sm,
     878             :                             const unsigned char *src_addr,
     879             :                             struct wpa_eapol_ie_parse *ie,
     880             :                             const u8 *assoc_resp_mdie)
     881             : {
     882             :         struct rsn_mdie *mdie;
     883             : 
     884          25 :         mdie = (struct rsn_mdie *) (ie->mdie + 2);
     885          50 :         if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
     886          25 :             os_memcmp(mdie->mobility_domain, sm->mobility_domain,
     887             :                       MOBILITY_DOMAIN_ID_LEN) != 0) {
     888           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
     889             :                         "not match with the current mobility domain");
     890           0 :                 return -1;
     891             :         }
     892             : 
     893          50 :         if (assoc_resp_mdie &&
     894          50 :             (assoc_resp_mdie[1] != ie->mdie[1] ||
     895          25 :              os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
     896           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
     897           0 :                 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
     898           0 :                             ie->mdie, 2 + ie->mdie[1]);
     899           0 :                 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
     900           0 :                             assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
     901           0 :                 return -1;
     902             :         }
     903             : 
     904          25 :         return 0;
     905             : }
     906             : 
     907             : 
     908          25 : static int ft_validate_ftie(struct wpa_sm *sm,
     909             :                             const unsigned char *src_addr,
     910             :                             struct wpa_eapol_ie_parse *ie,
     911             :                             const u8 *assoc_resp_ftie)
     912             : {
     913          25 :         if (ie->ftie == NULL) {
     914           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     915             :                         "FT: No FTIE in EAPOL-Key msg 3/4");
     916           0 :                 return -1;
     917             :         }
     918             : 
     919          25 :         if (assoc_resp_ftie == NULL)
     920           0 :                 return 0;
     921             : 
     922          50 :         if (assoc_resp_ftie[1] != ie->ftie[1] ||
     923          25 :             os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
     924           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
     925           0 :                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
     926           0 :                             ie->ftie, 2 + ie->ftie[1]);
     927           0 :                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
     928           0 :                             assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
     929           0 :                 return -1;
     930             :         }
     931             : 
     932          25 :         return 0;
     933             : }
     934             : 
     935             : 
     936          25 : static int ft_validate_rsnie(struct wpa_sm *sm,
     937             :                              const unsigned char *src_addr,
     938             :                              struct wpa_eapol_ie_parse *ie)
     939             : {
     940             :         struct wpa_ie_data rsn;
     941             : 
     942          25 :         if (!ie->rsn_ie)
     943           0 :                 return 0;
     944             : 
     945             :         /*
     946             :          * Verify that PMKR1Name from EAPOL-Key message 3/4
     947             :          * matches with the value we derived.
     948             :          */
     949          50 :         if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
     950          50 :             rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
     951           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
     952             :                         "FT 4-way handshake message 3/4");
     953           0 :                 return -1;
     954             :         }
     955             : 
     956          25 :         if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
     957             :         {
     958           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     959             :                         "FT: PMKR1Name mismatch in "
     960             :                         "FT 4-way handshake message 3/4");
     961           0 :                 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
     962           0 :                             rsn.pmkid, WPA_PMK_NAME_LEN);
     963           0 :                 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
     964           0 :                             sm->pmk_r1_name, WPA_PMK_NAME_LEN);
     965           0 :                 return -1;
     966             :         }
     967             : 
     968          25 :         return 0;
     969             : }
     970             : 
     971             : 
     972          25 : static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
     973             :                                          const unsigned char *src_addr,
     974             :                                          struct wpa_eapol_ie_parse *ie)
     975             : {
     976          25 :         const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
     977             : 
     978          25 :         if (sm->assoc_resp_ies) {
     979          25 :                 pos = sm->assoc_resp_ies;
     980          25 :                 end = pos + sm->assoc_resp_ies_len;
     981         100 :                 while (pos + 2 < end) {
     982          50 :                         if (pos + 2 + pos[1] > end)
     983           0 :                                 break;
     984          50 :                         switch (*pos) {
     985             :                         case WLAN_EID_MOBILITY_DOMAIN:
     986          25 :                                 mdie = pos;
     987          25 :                                 break;
     988             :                         case WLAN_EID_FAST_BSS_TRANSITION:
     989          25 :                                 ftie = pos;
     990          25 :                                 break;
     991             :                         }
     992          50 :                         pos += 2 + pos[1];
     993             :                 }
     994             :         }
     995             : 
     996          50 :         if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
     997          50 :             ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
     998          25 :             ft_validate_rsnie(sm, src_addr, ie) < 0)
     999           0 :                 return -1;
    1000             : 
    1001          25 :         return 0;
    1002             : }
    1003             : 
    1004             : #endif /* CONFIG_IEEE80211R */
    1005             : 
    1006             : 
    1007        1353 : static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
    1008             :                                       const unsigned char *src_addr,
    1009             :                                       struct wpa_eapol_ie_parse *ie)
    1010             : {
    1011        1353 :         if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
    1012          22 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1013             :                         "WPA: No WPA/RSN IE for this AP known. "
    1014             :                         "Trying to get from scan results");
    1015          22 :                 if (wpa_sm_get_beacon_ie(sm) < 0) {
    1016           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1017             :                                 "WPA: Could not find AP from "
    1018             :                                 "the scan results");
    1019             :                 } else {
    1020          22 :                         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
    1021             :                                 "WPA: Found the current AP from "
    1022             :                                 "updated scan results");
    1023             :                 }
    1024             :         }
    1025             : 
    1026        1356 :         if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
    1027           6 :             (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
    1028           1 :                 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
    1029             :                                        "with IE in Beacon/ProbeResp (no IE?)",
    1030             :                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
    1031             :                                        ie->rsn_ie, ie->rsn_ie_len);
    1032           1 :                 return -1;
    1033             :         }
    1034             : 
    1035        1399 :         if ((ie->wpa_ie && sm->ap_wpa_ie &&
    1036          94 :              (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
    1037        1399 :               os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
    1038        4010 :             (ie->rsn_ie && sm->ap_rsn_ie &&
    1039        2658 :              wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
    1040        1329 :                                 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
    1041             :                                 ie->rsn_ie, ie->rsn_ie_len))) {
    1042           1 :                 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
    1043             :                                        "with IE in Beacon/ProbeResp",
    1044             :                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
    1045             :                                        ie->rsn_ie, ie->rsn_ie_len);
    1046           1 :                 return -1;
    1047             :         }
    1048             : 
    1049        1372 :         if (sm->proto == WPA_PROTO_WPA &&
    1050          21 :             ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
    1051           0 :                 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
    1052             :                                        "detected - RSN was enabled and RSN IE "
    1053             :                                        "was in msg 3/4, but not in "
    1054             :                                        "Beacon/ProbeResp",
    1055             :                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
    1056             :                                        ie->rsn_ie, ie->rsn_ie_len);
    1057           0 :                 return -1;
    1058             :         }
    1059             : 
    1060             : #ifdef CONFIG_IEEE80211R
    1061        1376 :         if (wpa_key_mgmt_ft(sm->key_mgmt) &&
    1062          25 :             wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
    1063           0 :                 return -1;
    1064             : #endif /* CONFIG_IEEE80211R */
    1065             : 
    1066        1351 :         return 0;
    1067             : }
    1068             : 
    1069             : 
    1070             : /**
    1071             :  * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
    1072             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    1073             :  * @dst: Destination address for the frame
    1074             :  * @key: Pointer to the EAPOL-Key frame header
    1075             :  * @ver: Version bits from EAPOL-Key Key Info
    1076             :  * @key_info: Key Info
    1077             :  * @ptk: PTK to use for keyed hash and encryption
    1078             :  * Returns: 0 on success, -1 on failure
    1079             :  */
    1080        1350 : int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
    1081             :                                const struct wpa_eapol_key *key,
    1082             :                                u16 ver, u16 key_info,
    1083             :                                struct wpa_ptk *ptk)
    1084             : {
    1085             :         size_t mic_len, hdrlen, rlen;
    1086             :         struct wpa_eapol_key *reply;
    1087             :         struct wpa_eapol_key_192 *reply192;
    1088             :         u8 *rbuf, *key_mic;
    1089             : 
    1090        1350 :         mic_len = wpa_mic_len(sm->key_mgmt);
    1091        1350 :         hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
    1092        1350 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
    1093             :                                   hdrlen, &rlen, (void *) &reply);
    1094        1350 :         if (rbuf == NULL)
    1095           0 :                 return -1;
    1096        1350 :         reply192 = (struct wpa_eapol_key_192 *) reply;
    1097             : 
    1098        1373 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
    1099          23 :                        sm->proto == WPA_PROTO_OSEN) ?
    1100             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
    1101        1350 :         key_info &= WPA_KEY_INFO_SECURE;
    1102        1350 :         key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
    1103        1350 :         WPA_PUT_BE16(reply->key_info, key_info);
    1104        1350 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
    1105        1329 :                 WPA_PUT_BE16(reply->key_length, 0);
    1106             :         else
    1107          21 :                 os_memcpy(reply->key_length, key->key_length, 2);
    1108        1350 :         os_memcpy(reply->replay_counter, key->replay_counter,
    1109             :                   WPA_REPLAY_COUNTER_LEN);
    1110             : 
    1111        1350 :         key_mic = reply192->key_mic; /* same offset for reply and reply192 */
    1112        1350 :         if (mic_len == 24)
    1113           2 :                 WPA_PUT_BE16(reply192->key_data_length, 0);
    1114             :         else
    1115        1348 :                 WPA_PUT_BE16(reply->key_data_length, 0);
    1116             : 
    1117        1350 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
    1118        1350 :         wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
    1119             :                            rbuf, rlen, key_mic);
    1120             : 
    1121        1350 :         return 0;
    1122             : }
    1123             : 
    1124             : 
    1125        1355 : static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
    1126             :                                           const struct wpa_eapol_key *key,
    1127             :                                           u16 ver, const u8 *key_data,
    1128             :                                           size_t key_data_len)
    1129             : {
    1130             :         u16 key_info, keylen;
    1131             :         struct wpa_eapol_ie_parse ie;
    1132             : 
    1133        1355 :         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
    1134        1355 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
    1135             :                 "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
    1136             : 
    1137        1355 :         key_info = WPA_GET_BE16(key->key_info);
    1138             : 
    1139        1355 :         wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len);
    1140        1355 :         if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
    1141           1 :                 goto failed;
    1142        1354 :         if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
    1143           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1144             :                         "WPA: GTK IE in unencrypted key data");
    1145           1 :                 goto failed;
    1146             :         }
    1147             : #ifdef CONFIG_IEEE80211W
    1148        1353 :         if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
    1149           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1150             :                         "WPA: IGTK KDE in unencrypted key data");
    1151           0 :                 goto failed;
    1152             :         }
    1153             : 
    1154        1399 :         if (ie.igtk &&
    1155          90 :             wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
    1156          88 :             ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
    1157          44 :             (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
    1158           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1159             :                         "WPA: Invalid IGTK KDE length %lu",
    1160             :                         (unsigned long) ie.igtk_len);
    1161           0 :                 goto failed;
    1162             :         }
    1163             : #endif /* CONFIG_IEEE80211W */
    1164             : 
    1165        1353 :         if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
    1166           2 :                 goto failed;
    1167             : 
    1168        1351 :         if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
    1169           6 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1170             :                         "WPA: ANonce from message 1 of 4-Way Handshake "
    1171             :                         "differs from 3 of 4-Way Handshake - drop packet (src="
    1172           6 :                         MACSTR ")", MAC2STR(sm->bssid));
    1173           1 :                 goto failed;
    1174             :         }
    1175             : 
    1176        1350 :         keylen = WPA_GET_BE16(key->key_length);
    1177        1350 :         if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
    1178           7 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1179             :                         "WPA: Invalid %s key length %d (src=" MACSTR
    1180           1 :                         ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
    1181           6 :                         MAC2STR(sm->bssid));
    1182           1 :                 goto failed;
    1183             :         }
    1184             : 
    1185             : #ifdef CONFIG_P2P
    1186        1349 :         if (ie.ip_addr_alloc) {
    1187          72 :                 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
    1188          72 :                 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
    1189          72 :                             sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
    1190             :         }
    1191             : #endif /* CONFIG_P2P */
    1192             : 
    1193        1349 :         if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
    1194             :                                        &sm->ptk)) {
    1195           0 :                 goto failed;
    1196             :         }
    1197             : 
    1198             :         /* SNonce was successfully used in msg 3/4, so mark it to be renewed
    1199             :          * for the next 4-Way Handshake. If msg 3 is received again, the old
    1200             :          * SNonce will still be used to avoid changing PTK. */
    1201        1349 :         sm->renew_snonce = 1;
    1202             : 
    1203        1349 :         if (key_info & WPA_KEY_INFO_INSTALL) {
    1204        1349 :                 if (wpa_supplicant_install_ptk(sm, key))
    1205           0 :                         goto failed;
    1206             :         }
    1207             : 
    1208        1349 :         if (key_info & WPA_KEY_INFO_SECURE) {
    1209        1328 :                 wpa_sm_mlme_setprotection(
    1210        1328 :                         sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
    1211             :                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
    1212        1328 :                 eapol_sm_notify_portValid(sm->eapol, TRUE);
    1213             :         }
    1214        1349 :         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
    1215             : 
    1216        1349 :         if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
    1217           2 :                 wpa_supplicant_key_neg_complete(sm, sm->bssid,
    1218             :                                                 key_info & WPA_KEY_INFO_SECURE);
    1219        2672 :         } else if (ie.gtk &&
    1220        1325 :             wpa_supplicant_pairwise_gtk(sm, key,
    1221             :                                         ie.gtk, ie.gtk_len, key_info) < 0) {
    1222           2 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1223             :                         "RSN: Failed to configure GTK");
    1224           2 :                 goto failed;
    1225             :         }
    1226             : 
    1227        1347 :         if (ieee80211w_set_keys(sm, &ie) < 0) {
    1228           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1229             :                         "RSN: Failed to configure IGTK");
    1230           0 :                 goto failed;
    1231             :         }
    1232             : 
    1233        1347 :         if (ie.gtk)
    1234        1325 :                 wpa_sm_set_rekey_offload(sm);
    1235             : 
    1236        1347 :         if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
    1237             :                 struct rsn_pmksa_cache_entry *sa;
    1238             : 
    1239          12 :                 sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len,
    1240           4 :                                      sm->ptk.kck, sm->ptk.kck_len,
    1241           4 :                                      sm->bssid, sm->own_addr,
    1242           4 :                                      sm->network_ctx, sm->key_mgmt);
    1243           4 :                 if (!sm->cur_pmksa)
    1244           4 :                         sm->cur_pmksa = sa;
    1245             :         }
    1246             : 
    1247        1347 :         sm->msg_3_of_4_ok = 1;
    1248        2702 :         return;
    1249             : 
    1250             : failed:
    1251           8 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    1252             : }
    1253             : 
    1254             : 
    1255          12 : static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
    1256             :                                              const u8 *keydata,
    1257             :                                              size_t keydatalen,
    1258             :                                              u16 key_info,
    1259             :                                              struct wpa_gtk_data *gd)
    1260             : {
    1261             :         int maxkeylen;
    1262             :         struct wpa_eapol_ie_parse ie;
    1263             : 
    1264          12 :         wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
    1265          12 :         if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
    1266           0 :                 return -1;
    1267          12 :         if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
    1268           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1269             :                         "WPA: GTK IE in unencrypted key data");
    1270           1 :                 return -1;
    1271             :         }
    1272          11 :         if (ie.gtk == NULL) {
    1273           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1274             :                         "WPA: No GTK IE in Group Key msg 1/2");
    1275           1 :                 return -1;
    1276             :         }
    1277          10 :         maxkeylen = gd->gtk_len = ie.gtk_len - 2;
    1278             : 
    1279          10 :         if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
    1280             :                                               gd->gtk_len, maxkeylen,
    1281             :                                               &gd->key_rsc_len, &gd->alg))
    1282           1 :                 return -1;
    1283             : 
    1284          18 :         wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",
    1285           9 :                     ie.gtk, ie.gtk_len);
    1286           9 :         gd->keyidx = ie.gtk[0] & 0x3;
    1287           9 :         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
    1288           9 :                                                       !!(ie.gtk[0] & BIT(2)));
    1289           9 :         if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
    1290           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1291             :                         "RSN: Too long GTK in GTK IE (len=%lu)",
    1292           0 :                         (unsigned long) ie.gtk_len - 2);
    1293           0 :                 return -1;
    1294             :         }
    1295           9 :         os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
    1296             : 
    1297           9 :         if (ieee80211w_set_keys(sm, &ie) < 0)
    1298           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1299             :                         "RSN: Failed to configure IGTK");
    1300             : 
    1301           9 :         return 0;
    1302             : }
    1303             : 
    1304             : 
    1305          22 : static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
    1306             :                                              const struct wpa_eapol_key *key,
    1307             :                                              const u8 *key_data,
    1308             :                                              size_t key_data_len, u16 key_info,
    1309             :                                              u16 ver, struct wpa_gtk_data *gd)
    1310             : {
    1311             :         size_t maxkeylen;
    1312             :         u16 gtk_len;
    1313             : 
    1314          22 :         gtk_len = WPA_GET_BE16(key->key_length);
    1315          22 :         maxkeylen = key_data_len;
    1316          22 :         if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
    1317           1 :                 if (maxkeylen < 8) {
    1318           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1319             :                                 "WPA: Too short maxkeylen (%lu)",
    1320             :                                 (unsigned long) maxkeylen);
    1321           0 :                         return -1;
    1322             :                 }
    1323           1 :                 maxkeylen -= 8;
    1324             :         }
    1325             : 
    1326          44 :         if (gtk_len > maxkeylen ||
    1327          22 :             wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
    1328             :                                               gtk_len, maxkeylen,
    1329             :                                               &gd->key_rsc_len, &gd->alg))
    1330           0 :                 return -1;
    1331             : 
    1332          22 :         gd->gtk_len = gtk_len;
    1333          22 :         gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
    1334             :                 WPA_KEY_INFO_KEY_INDEX_SHIFT;
    1335          43 :         if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
    1336             :                 u8 ek[32];
    1337          21 :                 if (key_data_len > sizeof(gd->gtk)) {
    1338           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1339             :                                 "WPA: RC4 key data too long (%lu)",
    1340             :                                 (unsigned long) key_data_len);
    1341           0 :                         return -1;
    1342             :                 }
    1343          21 :                 os_memcpy(ek, key->key_iv, 16);
    1344          21 :                 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
    1345          21 :                 os_memcpy(gd->gtk, key_data, key_data_len);
    1346          21 :                 if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
    1347           0 :                         os_memset(ek, 0, sizeof(ek));
    1348           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
    1349             :                                 "WPA: RC4 failed");
    1350           0 :                         return -1;
    1351             :                 }
    1352          21 :                 os_memset(ek, 0, sizeof(ek));
    1353           1 :         } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
    1354           1 :                 if (maxkeylen % 8) {
    1355           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1356             :                                 "WPA: Unsupported AES-WRAP len %lu",
    1357             :                                 (unsigned long) maxkeylen);
    1358           0 :                         return -1;
    1359             :                 }
    1360           1 :                 if (maxkeylen > sizeof(gd->gtk)) {
    1361           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1362             :                                 "WPA: AES-WRAP key data "
    1363             :                                 "too long (keydatalen=%lu maxkeylen=%lu)",
    1364             :                                 (unsigned long) key_data_len,
    1365             :                                 (unsigned long) maxkeylen);
    1366           0 :                         return -1;
    1367             :                 }
    1368           1 :                 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8,
    1369           1 :                                key_data, gd->gtk)) {
    1370           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1371             :                                 "WPA: AES unwrap failed - could not decrypt "
    1372             :                                 "GTK");
    1373           0 :                         return -1;
    1374             :                 }
    1375             :         } else {
    1376           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1377             :                         "WPA: Unsupported key_info type %d", ver);
    1378           0 :                 return -1;
    1379             :         }
    1380          22 :         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
    1381          22 :                 sm, !!(key_info & WPA_KEY_INFO_TXRX));
    1382          22 :         return 0;
    1383             : }
    1384             : 
    1385             : 
    1386          31 : static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
    1387             :                                       const struct wpa_eapol_key *key,
    1388             :                                       int ver, u16 key_info)
    1389             : {
    1390             :         size_t mic_len, hdrlen, rlen;
    1391             :         struct wpa_eapol_key *reply;
    1392             :         struct wpa_eapol_key_192 *reply192;
    1393             :         u8 *rbuf, *key_mic;
    1394             : 
    1395          31 :         mic_len = wpa_mic_len(sm->key_mgmt);
    1396          31 :         hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
    1397          31 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
    1398             :                                   hdrlen, &rlen, (void *) &reply);
    1399          31 :         if (rbuf == NULL)
    1400           0 :                 return -1;
    1401          31 :         reply192 = (struct wpa_eapol_key_192 *) reply;
    1402             : 
    1403          53 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
    1404          22 :                        sm->proto == WPA_PROTO_OSEN) ?
    1405             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
    1406          31 :         key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
    1407          31 :         key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
    1408          31 :         WPA_PUT_BE16(reply->key_info, key_info);
    1409          31 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
    1410           9 :                 WPA_PUT_BE16(reply->key_length, 0);
    1411             :         else
    1412          22 :                 os_memcpy(reply->key_length, key->key_length, 2);
    1413          31 :         os_memcpy(reply->replay_counter, key->replay_counter,
    1414             :                   WPA_REPLAY_COUNTER_LEN);
    1415             : 
    1416          31 :         key_mic = reply192->key_mic; /* same offset for reply and reply192 */
    1417          31 :         if (mic_len == 24)
    1418           0 :                 WPA_PUT_BE16(reply192->key_data_length, 0);
    1419             :         else
    1420          31 :                 WPA_PUT_BE16(reply->key_data_length, 0);
    1421             : 
    1422          31 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
    1423          31 :         wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, sm->bssid,
    1424             :                            ETH_P_EAPOL, rbuf, rlen, key_mic);
    1425             : 
    1426          31 :         return 0;
    1427             : }
    1428             : 
    1429             : 
    1430          35 : static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
    1431             :                                           const unsigned char *src_addr,
    1432             :                                           const struct wpa_eapol_key *key,
    1433             :                                           const u8 *key_data,
    1434             :                                           size_t key_data_len, u16 ver)
    1435             : {
    1436             :         u16 key_info;
    1437             :         int rekey, ret;
    1438             :         struct wpa_gtk_data gd;
    1439             : 
    1440          35 :         if (!sm->msg_3_of_4_ok) {
    1441           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1442             :                         "WPA: Group Key Handshake started prior to completion of 4-way handshake");
    1443           1 :                 goto failed;
    1444             :         }
    1445             : 
    1446          34 :         os_memset(&gd, 0, sizeof(gd));
    1447             : 
    1448          34 :         rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
    1449          34 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
    1450             :                 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
    1451             : 
    1452          34 :         key_info = WPA_GET_BE16(key->key_info);
    1453             : 
    1454          34 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
    1455          12 :                 ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data,
    1456             :                                                         key_data_len, key_info,
    1457             :                                                         &gd);
    1458             :         } else {
    1459          22 :                 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data,
    1460             :                                                         key_data_len,
    1461             :                                                         key_info, ver, &gd);
    1462             :         }
    1463             : 
    1464          34 :         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
    1465             : 
    1466          34 :         if (ret)
    1467           3 :                 goto failed;
    1468             : 
    1469          62 :         if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
    1470          31 :             wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
    1471             :                 goto failed;
    1472          31 :         os_memset(&gd, 0, sizeof(gd));
    1473             : 
    1474          31 :         if (rekey) {
    1475          70 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
    1476             :                         "completed with " MACSTR " [GTK=%s]",
    1477          70 :                         MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
    1478          10 :                 wpa_sm_cancel_auth_timeout(sm);
    1479          10 :                 wpa_sm_set_state(sm, WPA_COMPLETED);
    1480             :         } else {
    1481          21 :                 wpa_supplicant_key_neg_complete(sm, sm->bssid,
    1482             :                                                 key_info &
    1483             :                                                 WPA_KEY_INFO_SECURE);
    1484             :         }
    1485             : 
    1486          31 :         wpa_sm_set_rekey_offload(sm);
    1487             : 
    1488          66 :         return;
    1489             : 
    1490             : failed:
    1491           4 :         os_memset(&gd, 0, sizeof(gd));
    1492           4 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    1493             : }
    1494             : 
    1495             : 
    1496        1406 : static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
    1497             :                                                struct wpa_eapol_key_192 *key,
    1498             :                                                u16 ver,
    1499             :                                                const u8 *buf, size_t len)
    1500             : {
    1501             :         u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
    1502        1406 :         int ok = 0;
    1503        1406 :         size_t mic_len = wpa_mic_len(sm->key_mgmt);
    1504             : 
    1505        1406 :         os_memcpy(mic, key->key_mic, mic_len);
    1506        1406 :         if (sm->tptk_set) {
    1507        1355 :                 os_memset(key->key_mic, 0, mic_len);
    1508        1355 :                 wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
    1509        1355 :                                   ver, buf, len, key->key_mic);
    1510        1355 :                 if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
    1511           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1512             :                                 "WPA: Invalid EAPOL-Key MIC "
    1513             :                                 "when using TPTK - ignoring TPTK");
    1514             :                 } else {
    1515        1355 :                         ok = 1;
    1516        1355 :                         sm->tptk_set = 0;
    1517        1355 :                         sm->ptk_set = 1;
    1518        1355 :                         os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
    1519        1355 :                         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    1520             :                 }
    1521             :         }
    1522             : 
    1523        1406 :         if (!ok && sm->ptk_set) {
    1524          51 :                 os_memset(key->key_mic, 0, mic_len);
    1525          51 :                 wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
    1526          51 :                                   ver, buf, len, key->key_mic);
    1527          51 :                 if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
    1528           1 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1529             :                                 "WPA: Invalid EAPOL-Key MIC - "
    1530             :                                 "dropping packet");
    1531           1 :                         return -1;
    1532             :                 }
    1533          50 :                 ok = 1;
    1534             :         }
    1535             : 
    1536        1405 :         if (!ok) {
    1537           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1538             :                         "WPA: Could not verify EAPOL-Key MIC - "
    1539             :                         "dropping packet");
    1540           0 :                 return -1;
    1541             :         }
    1542             : 
    1543        1405 :         os_memcpy(sm->rx_replay_counter, key->replay_counter,
    1544             :                   WPA_REPLAY_COUNTER_LEN);
    1545        1405 :         sm->rx_replay_counter_set = 1;
    1546        1405 :         return 0;
    1547             : }
    1548             : 
    1549             : 
    1550             : /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
    1551        1354 : static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
    1552             :                                            struct wpa_eapol_key *key, u16 ver,
    1553             :                                            u8 *key_data, size_t *key_data_len)
    1554             : {
    1555        1354 :         wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
    1556             :                     key_data, *key_data_len);
    1557        1354 :         if (!sm->ptk_set) {
    1558           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1559             :                         "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
    1560             :                         "Data");
    1561           0 :                 return -1;
    1562             :         }
    1563             : 
    1564             :         /* Decrypt key data here so that this operation does not need
    1565             :          * to be implemented separately for each message type. */
    1566        1356 :         if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
    1567             :                 u8 ek[32];
    1568           2 :                 os_memcpy(ek, key->key_iv, 16);
    1569           2 :                 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
    1570           2 :                 if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
    1571           0 :                         os_memset(ek, 0, sizeof(ek));
    1572           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
    1573             :                                 "WPA: RC4 failed");
    1574           0 :                         return -1;
    1575             :                 }
    1576           2 :                 os_memset(ek, 0, sizeof(ek));
    1577        1352 :         } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
    1578           6 :                    ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
    1579          10 :                    sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
    1580        1350 :                    wpa_key_mgmt_suite_b(sm->key_mgmt)) {
    1581             :                 u8 *buf;
    1582        1352 :                 if (*key_data_len < 8 || *key_data_len % 8) {
    1583           3 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1584             :                                 "WPA: Unsupported AES-WRAP len %u",
    1585           3 :                                 (unsigned int) *key_data_len);
    1586           3 :                         return -1;
    1587             :                 }
    1588        1349 :                 *key_data_len -= 8; /* AES-WRAP adds 8 bytes */
    1589        1349 :                 buf = os_malloc(*key_data_len);
    1590        1349 :                 if (buf == NULL) {
    1591           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1592             :                                 "WPA: No memory for AES-UNWRAP buffer");
    1593           0 :                         return -1;
    1594             :                 }
    1595        1349 :                 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8,
    1596             :                                key_data, buf)) {
    1597           3 :                         os_free(buf);
    1598           3 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1599             :                                 "WPA: AES unwrap failed - "
    1600             :                                 "could not decrypt EAPOL-Key key data");
    1601           3 :                         return -1;
    1602             :                 }
    1603        1346 :                 os_memcpy(key_data, buf, *key_data_len);
    1604        1346 :                 os_free(buf);
    1605        1346 :                 WPA_PUT_BE16(key->key_data_length, *key_data_len);
    1606             :         } else {
    1607           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1608             :                         "WPA: Unsupported key_info type %d", ver);
    1609           0 :                 return -1;
    1610             :         }
    1611        1348 :         wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
    1612             :                         key_data, *key_data_len);
    1613        1348 :         return 0;
    1614             : }
    1615             : 
    1616             : 
    1617             : /**
    1618             :  * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
    1619             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    1620             :  */
    1621          58 : void wpa_sm_aborted_cached(struct wpa_sm *sm)
    1622             : {
    1623          58 :         if (sm && sm->cur_pmksa) {
    1624          36 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1625             :                         "RSN: Cancelling PMKSA caching attempt");
    1626          36 :                 sm->cur_pmksa = NULL;
    1627             :         }
    1628          58 : }
    1629             : 
    1630             : 
    1631        2799 : static void wpa_eapol_key_dump(struct wpa_sm *sm,
    1632             :                                const struct wpa_eapol_key *key,
    1633             :                                unsigned int key_data_len,
    1634             :                                const u8 *mic, unsigned int mic_len)
    1635             : {
    1636             : #ifndef CONFIG_NO_STDOUT_DEBUG
    1637        2799 :         u16 key_info = WPA_GET_BE16(key->key_info);
    1638             : 
    1639        2799 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "  EAPOL-Key type=%d", key->type);
    1640        2799 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1641             :                 "  key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
    1642             :                 key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
    1643             :                 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
    1644             :                 WPA_KEY_INFO_KEY_INDEX_SHIFT,
    1645             :                 (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
    1646             :                 key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
    1647             :                 key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
    1648             :                 key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
    1649             :                 key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
    1650             :                 key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
    1651             :                 key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
    1652             :                 key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
    1653             :                 key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
    1654        2799 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1655             :                 "  key_length=%u key_data_length=%u",
    1656             :                 WPA_GET_BE16(key->key_length), key_data_len);
    1657        2799 :         wpa_hexdump(MSG_DEBUG, "  replay_counter",
    1658        2799 :                     key->replay_counter, WPA_REPLAY_COUNTER_LEN);
    1659        2799 :         wpa_hexdump(MSG_DEBUG, "  key_nonce", key->key_nonce, WPA_NONCE_LEN);
    1660        2799 :         wpa_hexdump(MSG_DEBUG, "  key_iv", key->key_iv, 16);
    1661        2799 :         wpa_hexdump(MSG_DEBUG, "  key_rsc", key->key_rsc, 8);
    1662        2799 :         wpa_hexdump(MSG_DEBUG, "  key_id (reserved)", key->key_id, 8);
    1663        2799 :         wpa_hexdump(MSG_DEBUG, "  key_mic", mic, mic_len);
    1664             : #endif /* CONFIG_NO_STDOUT_DEBUG */
    1665        2799 : }
    1666             : 
    1667             : 
    1668             : /**
    1669             :  * wpa_sm_rx_eapol - Process received WPA EAPOL frames
    1670             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    1671             :  * @src_addr: Source MAC address of the EAPOL packet
    1672             :  * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
    1673             :  * @len: Length of the EAPOL frame
    1674             :  * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
    1675             :  *
    1676             :  * This function is called for each received EAPOL frame. Other than EAPOL-Key
    1677             :  * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
    1678             :  * only processing WPA and WPA2 EAPOL-Key frames.
    1679             :  *
    1680             :  * The received EAPOL-Key packets are validated and valid packets are replied
    1681             :  * to. In addition, key material (PTK, GTK) is configured at the end of a
    1682             :  * successful key handshake.
    1683             :  */
    1684        2806 : int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
    1685             :                     const u8 *buf, size_t len)
    1686             : {
    1687             :         size_t plen, data_len, key_data_len;
    1688             :         const struct ieee802_1x_hdr *hdr;
    1689             :         struct wpa_eapol_key *key;
    1690             :         struct wpa_eapol_key_192 *key192;
    1691             :         u16 key_info, ver;
    1692        2806 :         u8 *tmp = NULL;
    1693        2806 :         int ret = -1;
    1694        2806 :         struct wpa_peerkey *peerkey = NULL;
    1695             :         u8 *key_data;
    1696             :         size_t mic_len, keyhdrlen;
    1697             : 
    1698             : #ifdef CONFIG_IEEE80211R
    1699        2806 :         sm->ft_completed = 0;
    1700             : #endif /* CONFIG_IEEE80211R */
    1701             : 
    1702        2806 :         mic_len = wpa_mic_len(sm->key_mgmt);
    1703        2806 :         keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key);
    1704             : 
    1705        2806 :         if (len < sizeof(*hdr) + keyhdrlen) {
    1706           4 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1707             :                         "WPA: EAPOL frame too short to be a WPA "
    1708             :                         "EAPOL-Key (len %lu, expecting at least %lu)",
    1709             :                         (unsigned long) len,
    1710             :                         (unsigned long) sizeof(*hdr) + keyhdrlen);
    1711           4 :                 return 0;
    1712             :         }
    1713             : 
    1714        2802 :         hdr = (const struct ieee802_1x_hdr *) buf;
    1715        2802 :         plen = be_to_host16(hdr->length);
    1716        2802 :         data_len = plen + sizeof(*hdr);
    1717        2802 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1718             :                 "IEEE 802.1X RX: version=%d type=%d length=%lu",
    1719             :                 hdr->version, hdr->type, (unsigned long) plen);
    1720             : 
    1721        2802 :         if (hdr->version < EAPOL_VERSION) {
    1722             :                 /* TODO: backwards compatibility */
    1723             :         }
    1724        2802 :         if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
    1725           0 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1726             :                         "WPA: EAPOL frame (type %u) discarded, "
    1727             :                         "not a Key frame", hdr->type);
    1728           0 :                 ret = 0;
    1729           0 :                 goto out;
    1730             :         }
    1731        2802 :         wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
    1732        2802 :         if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
    1733           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1734             :                         "WPA: EAPOL frame payload size %lu "
    1735             :                         "invalid (frame size %lu)",
    1736             :                         (unsigned long) plen, (unsigned long) len);
    1737           1 :                 ret = 0;
    1738           1 :                 goto out;
    1739             :         }
    1740        2801 :         if (data_len < len) {
    1741           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1742             :                         "WPA: ignoring %lu bytes after the IEEE 802.1X data",
    1743             :                         (unsigned long) len - data_len);
    1744             :         }
    1745             : 
    1746             :         /*
    1747             :          * Make a copy of the frame since we need to modify the buffer during
    1748             :          * MAC validation and Key Data decryption.
    1749             :          */
    1750        2801 :         tmp = os_malloc(data_len);
    1751        2801 :         if (tmp == NULL)
    1752           1 :                 goto out;
    1753        2800 :         os_memcpy(tmp, buf, data_len);
    1754        2800 :         key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
    1755        2800 :         key192 = (struct wpa_eapol_key_192 *)
    1756             :                 (tmp + sizeof(struct ieee802_1x_hdr));
    1757        2800 :         if (mic_len == 24)
    1758           4 :                 key_data = (u8 *) (key192 + 1);
    1759             :         else
    1760        2796 :                 key_data = (u8 *) (key + 1);
    1761             : 
    1762        2800 :         if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
    1763             :         {
    1764           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1765             :                         "WPA: EAPOL-Key type (%d) unknown, discarded",
    1766             :                         key->type);
    1767           1 :                 ret = 0;
    1768           1 :                 goto out;
    1769             :         }
    1770             : 
    1771        2799 :         if (mic_len == 24)
    1772           4 :                 key_data_len = WPA_GET_BE16(key192->key_data_length);
    1773             :         else
    1774        2795 :                 key_data_len = WPA_GET_BE16(key->key_data_length);
    1775        2799 :         wpa_eapol_key_dump(sm, key, key_data_len, key192->key_mic, mic_len);
    1776             : 
    1777        2799 :         if (key_data_len > plen - keyhdrlen) {
    1778           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
    1779             :                         "frame - key_data overflow (%u > %u)",
    1780             :                         (unsigned int) key_data_len,
    1781             :                         (unsigned int) (plen - keyhdrlen));
    1782           1 :                 goto out;
    1783             :         }
    1784             : 
    1785        2798 :         eapol_sm_notify_lower_layer_success(sm->eapol, 0);
    1786        2798 :         key_info = WPA_GET_BE16(key->key_info);
    1787        2798 :         ver = key_info & WPA_KEY_INFO_TYPE_MASK;
    1788        2798 :         if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
    1789             : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
    1790        2623 :             ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
    1791             : #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
    1792          15 :             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
    1793          22 :             !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
    1794           7 :             sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
    1795           3 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1796             :                         "WPA: Unsupported EAPOL-Key descriptor version %d",
    1797             :                         ver);
    1798           3 :                 goto out;
    1799             :         }
    1800             : 
    1801        2795 :         if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
    1802             :             ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
    1803           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1804             :                         "OSEN: Unsupported EAPOL-Key descriptor version %d",
    1805             :                         ver);
    1806           0 :                 goto out;
    1807             :         }
    1808             : 
    1809        2795 :         if (wpa_key_mgmt_suite_b(sm->key_mgmt) &&
    1810             :             ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
    1811           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1812             :                         "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
    1813             :                         ver);
    1814           0 :                 goto out;
    1815             :         }
    1816             : 
    1817             : #ifdef CONFIG_IEEE80211R
    1818        2795 :         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
    1819             :                 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
    1820          52 :                 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
    1821           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1822             :                                 "FT: AP did not use AES-128-CMAC");
    1823           0 :                         goto out;
    1824             :                 }
    1825             :         } else
    1826             : #endif /* CONFIG_IEEE80211R */
    1827             : #ifdef CONFIG_IEEE80211W
    1828        2743 :         if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
    1829          70 :                 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
    1830          12 :                     sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
    1831           4 :                     !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
    1832           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1833             :                                 "WPA: AP did not use the "
    1834             :                                 "negotiated AES-128-CMAC");
    1835           0 :                         goto out;
    1836             :                 }
    1837             :         } else
    1838             : #endif /* CONFIG_IEEE80211W */
    1839        5285 :         if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
    1840        5208 :             !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
    1841             :             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
    1842           2 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1843             :                         "WPA: CCMP is used, but EAPOL-Key "
    1844             :                         "descriptor version (%d) is not 2", ver);
    1845           3 :                 if (sm->group_cipher != WPA_CIPHER_CCMP &&
    1846           0 :                     !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
    1847             :                         /* Earlier versions of IEEE 802.11i did not explicitly
    1848             :                          * require version 2 descriptor for all EAPOL-Key
    1849             :                          * packets, so allow group keys to use version 1 if
    1850             :                          * CCMP is not used for them. */
    1851           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1852             :                                 "WPA: Backwards compatibility: allow invalid "
    1853             :                                 "version for non-CCMP group keys");
    1854           2 :                 } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
    1855           1 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1856             :                                 "WPA: Interoperability workaround: allow incorrect (should have been HMAC-SHA1), but stronger (is AES-128-CMAC), descriptor version to be used");
    1857             :                 } else
    1858           1 :                         goto out;
    1859        2681 :         } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
    1860           4 :                    !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
    1861             :                    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
    1862           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1863             :                         "WPA: GCMP is used, but EAPOL-Key "
    1864             :                         "descriptor version (%d) is not 2", ver);
    1865           0 :                 goto out;
    1866             :         }
    1867             : 
    1868             : #ifdef CONFIG_PEERKEY
    1869        2800 :         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
    1870          10 :                 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
    1871           4 :                         break;
    1872             :         }
    1873             : 
    1874        2794 :         if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
    1875           4 :                 if (!peerkey->initiator && peerkey->replay_counter_set &&
    1876           0 :                     os_memcmp(key->replay_counter, peerkey->replay_counter,
    1877             :                               WPA_REPLAY_COUNTER_LEN) <= 0) {
    1878           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1879             :                                 "RSN: EAPOL-Key Replay Counter did not "
    1880             :                                 "increase (STK) - dropping packet");
    1881           0 :                         goto out;
    1882           4 :                 } else if (peerkey->initiator) {
    1883             :                         u8 _tmp[WPA_REPLAY_COUNTER_LEN];
    1884           2 :                         os_memcpy(_tmp, key->replay_counter,
    1885             :                                   WPA_REPLAY_COUNTER_LEN);
    1886           2 :                         inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
    1887           2 :                         if (os_memcmp(_tmp, peerkey->replay_counter,
    1888             :                                       WPA_REPLAY_COUNTER_LEN) != 0) {
    1889           0 :                                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1890             :                                         "RSN: EAPOL-Key Replay "
    1891             :                                         "Counter did not match (STK) - "
    1892             :                                         "dropping packet");
    1893           0 :                                 goto out;
    1894             :                         }
    1895             :                 }
    1896             :         }
    1897             : 
    1898        2794 :         if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
    1899           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1900             :                         "RSN: Ack bit in key_info from STK peer");
    1901           0 :                 goto out;
    1902             :         }
    1903             : #endif /* CONFIG_PEERKEY */
    1904             : 
    1905        2981 :         if (!peerkey && sm->rx_replay_counter_set &&
    1906         187 :             os_memcmp(key->replay_counter, sm->rx_replay_counter,
    1907             :                       WPA_REPLAY_COUNTER_LEN) <= 0) {
    1908           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1909             :                         "WPA: EAPOL-Key Replay Counter did not increase - "
    1910             :                         "dropping packet");
    1911           1 :                 goto out;
    1912             :         }
    1913             : 
    1914        2793 :         if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
    1915             : #ifdef CONFIG_PEERKEY
    1916           3 :             && (peerkey == NULL || !peerkey->initiator)
    1917             : #endif /* CONFIG_PEERKEY */
    1918             :                 ) {
    1919           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1920             :                         "WPA: No Ack bit in key_info");
    1921           1 :                 goto out;
    1922             :         }
    1923             : 
    1924        2792 :         if (key_info & WPA_KEY_INFO_REQUEST) {
    1925           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1926             :                         "WPA: EAPOL-Key with Request bit - dropped");
    1927           1 :                 goto out;
    1928             :         }
    1929             : 
    1930        4197 :         if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
    1931        1406 :             wpa_supplicant_verify_eapol_key_mic(sm, key192, ver, tmp, data_len))
    1932           1 :                 goto out;
    1933             : 
    1934             : #ifdef CONFIG_PEERKEY
    1935        2793 :         if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
    1936           3 :             peerkey_verify_eapol_key_mic(sm, peerkey, key192, ver, tmp,
    1937             :                                          data_len))
    1938           0 :                 goto out;
    1939             : #endif /* CONFIG_PEERKEY */
    1940             : 
    1941        5516 :         if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
    1942        2726 :             (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
    1943        1354 :                 if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data,
    1944             :                                                     &key_data_len))
    1945           6 :                         goto out;
    1946             :         }
    1947             : 
    1948        2784 :         if (key_info & WPA_KEY_INFO_KEY_TYPE) {
    1949        2741 :                 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
    1950           1 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1951             :                                 "WPA: Ignored EAPOL-Key (Pairwise) with "
    1952             :                                 "non-zero key index");
    1953           1 :                         goto out;
    1954             :                 }
    1955        2740 :                 if (peerkey) {
    1956             :                         /* PeerKey 4-Way Handshake */
    1957           4 :                         peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
    1958             :                                               key_data, key_data_len);
    1959        2736 :                 } else if (key_info & WPA_KEY_INFO_MIC) {
    1960             :                         /* 3/4 4-Way Handshake */
    1961        1355 :                         wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
    1962             :                                                       key_data_len);
    1963             :                 } else {
    1964             :                         /* 1/4 4-Way Handshake */
    1965        1381 :                         wpa_supplicant_process_1_of_4(sm, src_addr, key,
    1966             :                                                       ver, key_data,
    1967             :                                                       key_data_len);
    1968             :                 }
    1969          43 :         } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
    1970             :                 /* PeerKey SMK Handshake */
    1971           8 :                 peerkey_rx_eapol_smk(sm, src_addr, key, key_data_len, key_info,
    1972             :                                      ver);
    1973             :         } else {
    1974          35 :                 if (key_info & WPA_KEY_INFO_MIC) {
    1975             :                         /* 1/2 Group Key Handshake */
    1976          35 :                         wpa_supplicant_process_1_of_2(sm, src_addr, key,
    1977             :                                                       key_data, key_data_len,
    1978             :                                                       ver);
    1979             :                 } else {
    1980           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1981             :                                 "WPA: EAPOL-Key (Group) without Mic bit - "
    1982             :                                 "dropped");
    1983             :                 }
    1984             :         }
    1985             : 
    1986        2783 :         ret = 1;
    1987             : 
    1988             : out:
    1989        2802 :         bin_clear_free(tmp, data_len);
    1990        2802 :         return ret;
    1991             : }
    1992             : 
    1993             : 
    1994             : #ifdef CONFIG_CTRL_IFACE
    1995          88 : static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
    1996             : {
    1997          88 :         switch (sm->key_mgmt) {
    1998             :         case WPA_KEY_MGMT_IEEE8021X:
    1999          40 :                 return ((sm->proto == WPA_PROTO_RSN ||
    2000           8 :                          sm->proto == WPA_PROTO_OSEN) ?
    2001          24 :                         RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
    2002             :                         WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
    2003             :         case WPA_KEY_MGMT_PSK:
    2004          16 :                 return (sm->proto == WPA_PROTO_RSN ?
    2005           8 :                         RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
    2006             :                         WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
    2007             : #ifdef CONFIG_IEEE80211R
    2008             :         case WPA_KEY_MGMT_FT_IEEE8021X:
    2009           8 :                 return RSN_AUTH_KEY_MGMT_FT_802_1X;
    2010             :         case WPA_KEY_MGMT_FT_PSK:
    2011           8 :                 return RSN_AUTH_KEY_MGMT_FT_PSK;
    2012             : #endif /* CONFIG_IEEE80211R */
    2013             : #ifdef CONFIG_IEEE80211W
    2014             :         case WPA_KEY_MGMT_IEEE8021X_SHA256:
    2015           8 :                 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
    2016             :         case WPA_KEY_MGMT_PSK_SHA256:
    2017          16 :                 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
    2018             : #endif /* CONFIG_IEEE80211W */
    2019             :         case WPA_KEY_MGMT_CCKM:
    2020           0 :                 return (sm->proto == WPA_PROTO_RSN ?
    2021             :                         RSN_AUTH_KEY_MGMT_CCKM:
    2022             :                         WPA_AUTH_KEY_MGMT_CCKM);
    2023             :         case WPA_KEY_MGMT_WPA_NONE:
    2024           0 :                 return WPA_AUTH_KEY_MGMT_NONE;
    2025             :         case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
    2026           0 :                 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
    2027             :         case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
    2028           0 :                 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
    2029             :         default:
    2030          24 :                 return 0;
    2031             :         }
    2032             : }
    2033             : 
    2034             : 
    2035             : #define RSN_SUITE "%02x-%02x-%02x-%d"
    2036             : #define RSN_SUITE_ARG(s) \
    2037             : ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
    2038             : 
    2039             : /**
    2040             :  * wpa_sm_get_mib - Dump text list of MIB entries
    2041             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2042             :  * @buf: Buffer for the list
    2043             :  * @buflen: Length of the buffer
    2044             :  * Returns: Number of bytes written to buffer
    2045             :  *
    2046             :  * This function is used fetch dot11 MIB variables.
    2047             :  */
    2048          11 : int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
    2049             : {
    2050             :         char pmkid_txt[PMKID_LEN * 2 + 1];
    2051             :         int rsna, ret;
    2052             :         size_t len;
    2053             : 
    2054          11 :         if (sm->cur_pmksa) {
    2055           2 :                 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
    2056           2 :                                  sm->cur_pmksa->pmkid, PMKID_LEN);
    2057             :         } else
    2058           9 :                 pmkid_txt[0] = '\0';
    2059             : 
    2060          18 :         if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
    2061          15 :              wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
    2062           8 :             sm->proto == WPA_PROTO_RSN)
    2063           6 :                 rsna = 1;
    2064             :         else
    2065           5 :                 rsna = 0;
    2066             : 
    2067          22 :         ret = os_snprintf(buf, buflen,
    2068             :                           "dot11RSNAOptionImplemented=TRUE\n"
    2069             :                           "dot11RSNAPreauthenticationImplemented=TRUE\n"
    2070             :                           "dot11RSNAEnabled=%s\n"
    2071             :                           "dot11RSNAPreauthenticationEnabled=%s\n"
    2072             :                           "dot11RSNAConfigVersion=%d\n"
    2073             :                           "dot11RSNAConfigPairwiseKeysSupported=5\n"
    2074             :                           "dot11RSNAConfigGroupCipherSize=%d\n"
    2075             :                           "dot11RSNAConfigPMKLifetime=%d\n"
    2076             :                           "dot11RSNAConfigPMKReauthThreshold=%d\n"
    2077             :                           "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
    2078             :                           "dot11RSNAConfigSATimeout=%d\n",
    2079             :                           rsna ? "TRUE" : "FALSE",
    2080             :                           rsna ? "TRUE" : "FALSE",
    2081             :                           RSN_VERSION,
    2082          11 :                           wpa_cipher_key_len(sm->group_cipher) * 8,
    2083             :                           sm->dot11RSNAConfigPMKLifetime,
    2084             :                           sm->dot11RSNAConfigPMKReauthThreshold,
    2085             :                           sm->dot11RSNAConfigSATimeout);
    2086          11 :         if (os_snprintf_error(buflen, ret))
    2087           0 :                 return 0;
    2088          11 :         len = ret;
    2089             : 
    2090         275 :         ret = os_snprintf(
    2091             :                 buf + len, buflen - len,
    2092             :                 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
    2093             :                 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
    2094             :                 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
    2095             :                 "dot11RSNAPMKIDUsed=%s\n"
    2096             :                 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
    2097             :                 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
    2098             :                 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
    2099             :                 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
    2100             :                 "dot11RSNA4WayHandshakeFailures=%u\n",
    2101          44 :                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
    2102          44 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    2103             :                                                   sm->pairwise_cipher)),
    2104          44 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    2105             :                                                   sm->group_cipher)),
    2106             :                 pmkid_txt,
    2107          44 :                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
    2108          44 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    2109             :                                                   sm->pairwise_cipher)),
    2110          44 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    2111             :                                                   sm->group_cipher)),
    2112             :                 sm->dot11RSNA4WayHandshakeFailures);
    2113          11 :         if (!os_snprintf_error(buflen - len, ret))
    2114          11 :                 len += ret;
    2115             : 
    2116          11 :         return (int) len;
    2117             : }
    2118             : #endif /* CONFIG_CTRL_IFACE */
    2119             : 
    2120             : 
    2121         656 : static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
    2122             :                                  void *ctx, enum pmksa_free_reason reason)
    2123             : {
    2124         656 :         struct wpa_sm *sm = ctx;
    2125         656 :         int deauth = 0;
    2126             : 
    2127         656 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
    2128             :                 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
    2129             : 
    2130         656 :         if (sm->cur_pmksa == entry) {
    2131          37 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2132             :                         "RSN: %s current PMKSA entry",
    2133             :                         reason == PMKSA_REPLACE ? "replaced" : "removed");
    2134          37 :                 pmksa_cache_clear_current(sm);
    2135             : 
    2136             :                 /*
    2137             :                  * If an entry is simply being replaced, there's no need to
    2138             :                  * deauthenticate because it will be immediately re-added.
    2139             :                  * This happens when EAP authentication is completed again
    2140             :                  * (reauth or failed PMKSA caching attempt).
    2141             :                  */
    2142          37 :                 if (reason != PMKSA_REPLACE)
    2143          34 :                         deauth = 1;
    2144             :         }
    2145             : 
    2146         657 :         if (reason == PMKSA_EXPIRE &&
    2147           2 :             (sm->pmk_len == entry->pmk_len &&
    2148           1 :              os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
    2149           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2150             :                         "RSN: deauthenticating due to expired PMK");
    2151           1 :                 pmksa_cache_clear_current(sm);
    2152           1 :                 deauth = 1;
    2153             :         }
    2154             : 
    2155         656 :         if (deauth) {
    2156          35 :                 os_memset(sm->pmk, 0, sizeof(sm->pmk));
    2157          35 :                 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    2158             :         }
    2159         656 : }
    2160             : 
    2161             : 
    2162             : /**
    2163             :  * wpa_sm_init - Initialize WPA state machine
    2164             :  * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
    2165             :  * Returns: Pointer to the allocated WPA state machine data
    2166             :  *
    2167             :  * This function is used to allocate a new WPA state machine and the returned
    2168             :  * value is passed to all WPA state machine calls.
    2169             :  */
    2170         287 : struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
    2171             : {
    2172             :         struct wpa_sm *sm;
    2173             : 
    2174         287 :         sm = os_zalloc(sizeof(*sm));
    2175         287 :         if (sm == NULL)
    2176           1 :                 return NULL;
    2177         286 :         dl_list_init(&sm->pmksa_candidates);
    2178         286 :         sm->renew_snonce = 1;
    2179         286 :         sm->ctx = ctx;
    2180             : 
    2181         286 :         sm->dot11RSNAConfigPMKLifetime = 43200;
    2182         286 :         sm->dot11RSNAConfigPMKReauthThreshold = 70;
    2183         286 :         sm->dot11RSNAConfigSATimeout = 60;
    2184             : 
    2185         286 :         sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
    2186         286 :         if (sm->pmksa == NULL) {
    2187           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
    2188             :                         "RSN: PMKSA cache initialization failed");
    2189           1 :                 os_free(sm);
    2190           1 :                 return NULL;
    2191             :         }
    2192             : 
    2193         285 :         return sm;
    2194             : }
    2195             : 
    2196             : 
    2197             : /**
    2198             :  * wpa_sm_deinit - Deinitialize WPA state machine
    2199             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2200             :  */
    2201         302 : void wpa_sm_deinit(struct wpa_sm *sm)
    2202             : {
    2203         302 :         if (sm == NULL)
    2204         319 :                 return;
    2205         285 :         pmksa_cache_deinit(sm->pmksa);
    2206         285 :         eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
    2207         285 :         eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
    2208         285 :         os_free(sm->assoc_wpa_ie);
    2209         285 :         os_free(sm->ap_wpa_ie);
    2210         285 :         os_free(sm->ap_rsn_ie);
    2211         285 :         wpa_sm_drop_sa(sm);
    2212         285 :         os_free(sm->ctx);
    2213         285 :         peerkey_deinit(sm);
    2214             : #ifdef CONFIG_IEEE80211R
    2215         285 :         os_free(sm->assoc_resp_ies);
    2216             : #endif /* CONFIG_IEEE80211R */
    2217         285 :         os_free(sm);
    2218             : }
    2219             : 
    2220             : 
    2221             : /**
    2222             :  * wpa_sm_notify_assoc - Notify WPA state machine about association
    2223             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2224             :  * @bssid: The BSSID of the new association
    2225             :  *
    2226             :  * This function is called to let WPA state machine know that the connection
    2227             :  * was established.
    2228             :  */
    2229        2582 : void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
    2230             : {
    2231        2582 :         int clear_ptk = 1;
    2232             : 
    2233        2582 :         if (sm == NULL)
    2234        2582 :                 return;
    2235             : 
    2236        2582 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2237             :                 "WPA: Association event - clear replay counter");
    2238        2582 :         os_memcpy(sm->bssid, bssid, ETH_ALEN);
    2239        2582 :         os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
    2240        2582 :         sm->rx_replay_counter_set = 0;
    2241        2582 :         sm->renew_snonce = 1;
    2242        2582 :         if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
    2243           0 :                 rsn_preauth_deinit(sm);
    2244             : 
    2245             : #ifdef CONFIG_IEEE80211R
    2246        2582 :         if (wpa_ft_is_completed(sm)) {
    2247             :                 /*
    2248             :                  * Clear portValid to kick EAPOL state machine to re-enter
    2249             :                  * AUTHENTICATED state to get the EAPOL port Authorized.
    2250             :                  */
    2251         221 :                 eapol_sm_notify_portValid(sm->eapol, FALSE);
    2252         221 :                 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
    2253             : 
    2254             :                 /* Prepare for the next transition */
    2255         221 :                 wpa_ft_prepare_auth_request(sm, NULL);
    2256             : 
    2257         221 :                 clear_ptk = 0;
    2258             :         }
    2259             : #endif /* CONFIG_IEEE80211R */
    2260             : 
    2261        2582 :         if (clear_ptk) {
    2262             :                 /*
    2263             :                  * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
    2264             :                  * this is not part of a Fast BSS Transition.
    2265             :                  */
    2266        2361 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
    2267        2361 :                 sm->ptk_set = 0;
    2268        2361 :                 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
    2269        2361 :                 sm->tptk_set = 0;
    2270        2361 :                 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    2271             :         }
    2272             : 
    2273             : #ifdef CONFIG_TDLS
    2274        2582 :         wpa_tdls_assoc(sm);
    2275             : #endif /* CONFIG_TDLS */
    2276             : 
    2277             : #ifdef CONFIG_P2P
    2278        2582 :         os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
    2279             : #endif /* CONFIG_P2P */
    2280             : }
    2281             : 
    2282             : 
    2283             : /**
    2284             :  * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
    2285             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2286             :  *
    2287             :  * This function is called to let WPA state machine know that the connection
    2288             :  * was lost. This will abort any existing pre-authentication session.
    2289             :  */
    2290        2430 : void wpa_sm_notify_disassoc(struct wpa_sm *sm)
    2291             : {
    2292        2430 :         eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
    2293        2430 :         eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
    2294        2430 :         peerkey_deinit(sm);
    2295        2430 :         rsn_preauth_deinit(sm);
    2296        2430 :         pmksa_cache_clear_current(sm);
    2297        2430 :         if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
    2298          14 :                 sm->dot11RSNA4WayHandshakeFailures++;
    2299             : #ifdef CONFIG_TDLS
    2300        2430 :         wpa_tdls_disassoc(sm);
    2301             : #endif /* CONFIG_TDLS */
    2302             : 
    2303             :         /* Keys are not needed in the WPA state machine anymore */
    2304        2430 :         wpa_sm_drop_sa(sm);
    2305             : 
    2306        2430 :         sm->msg_3_of_4_ok = 0;
    2307        2430 : }
    2308             : 
    2309             : 
    2310             : /**
    2311             :  * wpa_sm_set_pmk - Set PMK
    2312             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2313             :  * @pmk: The new PMK
    2314             :  * @pmk_len: The length of the new PMK in bytes
    2315             :  * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
    2316             :  *
    2317             :  * Configure the PMK for WPA state machine.
    2318             :  */
    2319         917 : void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
    2320             :                     const u8 *bssid)
    2321             : {
    2322         917 :         if (sm == NULL)
    2323         917 :                 return;
    2324             : 
    2325         917 :         sm->pmk_len = pmk_len;
    2326         917 :         os_memcpy(sm->pmk, pmk, pmk_len);
    2327             : 
    2328             : #ifdef CONFIG_IEEE80211R
    2329             :         /* Set XXKey to be PSK for FT key derivation */
    2330         917 :         sm->xxkey_len = pmk_len;
    2331         917 :         os_memcpy(sm->xxkey, pmk, pmk_len);
    2332             : #endif /* CONFIG_IEEE80211R */
    2333             : 
    2334         917 :         if (bssid) {
    2335          54 :                 pmksa_cache_add(sm->pmksa, pmk, pmk_len, NULL, 0,
    2336          27 :                                 bssid, sm->own_addr,
    2337          27 :                                 sm->network_ctx, sm->key_mgmt);
    2338             :         }
    2339             : }
    2340             : 
    2341             : 
    2342             : /**
    2343             :  * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
    2344             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2345             :  *
    2346             :  * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
    2347             :  * will be cleared.
    2348             :  */
    2349        1055 : void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
    2350             : {
    2351        1055 :         if (sm == NULL)
    2352        1055 :                 return;
    2353             : 
    2354        1055 :         if (sm->cur_pmksa) {
    2355         103 :                 sm->pmk_len = sm->cur_pmksa->pmk_len;
    2356         103 :                 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
    2357             :         } else {
    2358         952 :                 sm->pmk_len = PMK_LEN;
    2359         952 :                 os_memset(sm->pmk, 0, PMK_LEN);
    2360             :         }
    2361             : }
    2362             : 
    2363             : 
    2364             : /**
    2365             :  * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
    2366             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2367             :  * @fast_reauth: Whether fast reauthentication (EAP) is allowed
    2368             :  */
    2369         272 : void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
    2370             : {
    2371         272 :         if (sm)
    2372         272 :                 sm->fast_reauth = fast_reauth;
    2373         272 : }
    2374             : 
    2375             : 
    2376             : /**
    2377             :  * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
    2378             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2379             :  * @scard_ctx: Context pointer for smartcard related callback functions
    2380             :  */
    2381         288 : void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
    2382             : {
    2383         288 :         if (sm == NULL)
    2384         305 :                 return;
    2385         271 :         sm->scard_ctx = scard_ctx;
    2386         271 :         if (sm->preauth_eapol)
    2387           0 :                 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
    2388             : }
    2389             : 
    2390             : 
    2391             : /**
    2392             :  * wpa_sm_set_config - Notification of current configration change
    2393             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2394             :  * @config: Pointer to current network configuration
    2395             :  *
    2396             :  * Notify WPA state machine that configuration has changed. config will be
    2397             :  * stored as a backpointer to network configuration. This can be %NULL to clear
    2398             :  * the stored pointed.
    2399             :  */
    2400        6043 : void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
    2401             : {
    2402        6043 :         if (!sm)
    2403        6047 :                 return;
    2404             : 
    2405        6039 :         if (config) {
    2406        2579 :                 sm->network_ctx = config->network_ctx;
    2407        2579 :                 sm->peerkey_enabled = config->peerkey_enabled;
    2408        2579 :                 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
    2409        2579 :                 sm->proactive_key_caching = config->proactive_key_caching;
    2410        2579 :                 sm->eap_workaround = config->eap_workaround;
    2411        2579 :                 sm->eap_conf_ctx = config->eap_conf_ctx;
    2412        2579 :                 if (config->ssid) {
    2413        2465 :                         os_memcpy(sm->ssid, config->ssid, config->ssid_len);
    2414        2465 :                         sm->ssid_len = config->ssid_len;
    2415             :                 } else
    2416         114 :                         sm->ssid_len = 0;
    2417        2579 :                 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
    2418        2579 :                 sm->p2p = config->p2p;
    2419             :         } else {
    2420        3460 :                 sm->network_ctx = NULL;
    2421        3460 :                 sm->peerkey_enabled = 0;
    2422        3460 :                 sm->allowed_pairwise_cipher = 0;
    2423        3460 :                 sm->proactive_key_caching = 0;
    2424        3460 :                 sm->eap_workaround = 0;
    2425        3460 :                 sm->eap_conf_ctx = NULL;
    2426        3460 :                 sm->ssid_len = 0;
    2427        3460 :                 sm->wpa_ptk_rekey = 0;
    2428        3460 :                 sm->p2p = 0;
    2429             :         }
    2430             : }
    2431             : 
    2432             : 
    2433             : /**
    2434             :  * wpa_sm_set_own_addr - Set own MAC address
    2435             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2436             :  * @addr: Own MAC address
    2437             :  */
    2438         576 : void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
    2439             : {
    2440         576 :         if (sm)
    2441         576 :                 os_memcpy(sm->own_addr, addr, ETH_ALEN);
    2442         576 : }
    2443             : 
    2444             : 
    2445             : /**
    2446             :  * wpa_sm_set_ifname - Set network interface name
    2447             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2448             :  * @ifname: Interface name
    2449             :  * @bridge_ifname: Optional bridge interface name (for pre-auth)
    2450             :  */
    2451         271 : void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
    2452             :                        const char *bridge_ifname)
    2453             : {
    2454         271 :         if (sm) {
    2455         271 :                 sm->ifname = ifname;
    2456         271 :                 sm->bridge_ifname = bridge_ifname;
    2457             :         }
    2458         271 : }
    2459             : 
    2460             : 
    2461             : /**
    2462             :  * wpa_sm_set_eapol - Set EAPOL state machine pointer
    2463             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2464             :  * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
    2465             :  */
    2466         560 : void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
    2467             : {
    2468         560 :         if (sm)
    2469         543 :                 sm->eapol = eapol;
    2470         560 : }
    2471             : 
    2472             : 
    2473             : /**
    2474             :  * wpa_sm_set_param - Set WPA state machine parameters
    2475             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2476             :  * @param: Parameter field
    2477             :  * @value: Parameter value
    2478             :  * Returns: 0 on success, -1 on failure
    2479             :  */
    2480       26771 : int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
    2481             :                      unsigned int value)
    2482             : {
    2483       26771 :         int ret = 0;
    2484             : 
    2485       26771 :         if (sm == NULL)
    2486           0 :                 return -1;
    2487             : 
    2488       26771 :         switch (param) {
    2489             :         case RSNA_PMK_LIFETIME:
    2490        3344 :                 if (value > 0)
    2491        3343 :                         sm->dot11RSNAConfigPMKLifetime = value;
    2492             :                 else
    2493           1 :                         ret = -1;
    2494        3344 :                 break;
    2495             :         case RSNA_PMK_REAUTH_THRESHOLD:
    2496        3343 :                 if (value > 0 && value <= 100)
    2497        3342 :                         sm->dot11RSNAConfigPMKReauthThreshold = value;
    2498             :                 else
    2499           1 :                         ret = -1;
    2500        3343 :                 break;
    2501             :         case RSNA_SA_TIMEOUT:
    2502        3345 :                 if (value > 0)
    2503        3344 :                         sm->dot11RSNAConfigSATimeout = value;
    2504             :                 else
    2505           1 :                         ret = -1;
    2506        3345 :                 break;
    2507             :         case WPA_PARAM_PROTO:
    2508        1911 :                 sm->proto = value;
    2509        1911 :                 break;
    2510             :         case WPA_PARAM_PAIRWISE:
    2511        2589 :                 sm->pairwise_cipher = value;
    2512        2589 :                 break;
    2513             :         case WPA_PARAM_GROUP:
    2514        2589 :                 sm->group_cipher = value;
    2515        2589 :                 break;
    2516             :         case WPA_PARAM_KEY_MGMT:
    2517        2589 :                 sm->key_mgmt = value;
    2518        2589 :                 break;
    2519             : #ifdef CONFIG_IEEE80211W
    2520             :         case WPA_PARAM_MGMT_GROUP:
    2521        2575 :                 sm->mgmt_group_cipher = value;
    2522        2575 :                 break;
    2523             : #endif /* CONFIG_IEEE80211W */
    2524             :         case WPA_PARAM_RSN_ENABLED:
    2525        2590 :                 sm->rsn_enabled = value;
    2526        2590 :                 break;
    2527             :         case WPA_PARAM_MFP:
    2528        1896 :                 sm->mfp = value;
    2529        1896 :                 break;
    2530             :         default:
    2531           0 :                 break;
    2532             :         }
    2533             : 
    2534       26771 :         return ret;
    2535             : }
    2536             : 
    2537             : 
    2538             : /**
    2539             :  * wpa_sm_get_status - Get WPA state machine
    2540             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2541             :  * @buf: Buffer for status information
    2542             :  * @buflen: Maximum buffer length
    2543             :  * @verbose: Whether to include verbose status information
    2544             :  * Returns: Number of bytes written to buf.
    2545             :  *
    2546             :  * Query WPA state machine for status information. This function fills in
    2547             :  * a text area with current status information. If the buffer (buf) is not
    2548             :  * large enough, status information will be truncated to fit the buffer.
    2549             :  */
    2550        1815 : int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
    2551             :                       int verbose)
    2552             : {
    2553        1815 :         char *pos = buf, *end = buf + buflen;
    2554             :         int ret;
    2555             : 
    2556        7260 :         ret = os_snprintf(pos, end - pos,
    2557             :                           "pairwise_cipher=%s\n"
    2558             :                           "group_cipher=%s\n"
    2559             :                           "key_mgmt=%s\n",
    2560        1815 :                           wpa_cipher_txt(sm->pairwise_cipher),
    2561        1815 :                           wpa_cipher_txt(sm->group_cipher),
    2562        3630 :                           wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
    2563        1815 :         if (os_snprintf_error(end - pos, ret))
    2564           0 :                 return pos - buf;
    2565        1815 :         pos += ret;
    2566             : 
    2567        1815 :         if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
    2568             :                 struct wpa_ie_data rsn;
    2569         496 :                 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
    2570         496 :                     >= 0 &&
    2571         496 :                     rsn.capabilities & (WPA_CAPABILITY_MFPR |
    2572             :                                         WPA_CAPABILITY_MFPC)) {
    2573          51 :                         ret = os_snprintf(pos, end - pos, "pmf=%d\n",
    2574          51 :                                           (rsn.capabilities &
    2575             :                                            WPA_CAPABILITY_MFPR) ? 2 : 1);
    2576          51 :                         if (os_snprintf_error(end - pos, ret))
    2577           0 :                                 return pos - buf;
    2578          51 :                         pos += ret;
    2579             :                 }
    2580             :         }
    2581             : 
    2582        1815 :         return pos - buf;
    2583             : }
    2584             : 
    2585             : 
    2586          50 : int wpa_sm_pmf_enabled(struct wpa_sm *sm)
    2587             : {
    2588             :         struct wpa_ie_data rsn;
    2589             : 
    2590          50 :         if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
    2591          43 :                 return 0;
    2592             : 
    2593          14 :         if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
    2594           7 :             rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
    2595           7 :                 return 1;
    2596             : 
    2597           0 :         return 0;
    2598             : }
    2599             : 
    2600             : 
    2601             : /**
    2602             :  * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
    2603             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2604             :  * @wpa_ie: Pointer to buffer for WPA/RSN IE
    2605             :  * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
    2606             :  * Returns: 0 on success, -1 on failure
    2607             :  */
    2608        1910 : int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
    2609             :                                     size_t *wpa_ie_len)
    2610             : {
    2611             :         int res;
    2612             : 
    2613        1910 :         if (sm == NULL)
    2614           0 :                 return -1;
    2615             : 
    2616        1910 :         res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
    2617        1910 :         if (res < 0)
    2618           0 :                 return -1;
    2619        1910 :         *wpa_ie_len = res;
    2620             : 
    2621        1910 :         wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
    2622             :                     wpa_ie, *wpa_ie_len);
    2623             : 
    2624        1910 :         if (sm->assoc_wpa_ie == NULL) {
    2625             :                 /*
    2626             :                  * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
    2627             :                  * the correct version of the IE even if PMKSA caching is
    2628             :                  * aborted (which would remove PMKID from IE generation).
    2629             :                  */
    2630         373 :                 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
    2631         373 :                 if (sm->assoc_wpa_ie == NULL)
    2632           0 :                         return -1;
    2633             : 
    2634         373 :                 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
    2635         373 :                 sm->assoc_wpa_ie_len = *wpa_ie_len;
    2636             :         }
    2637             : 
    2638        1910 :         return 0;
    2639             : }
    2640             : 
    2641             : 
    2642             : /**
    2643             :  * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
    2644             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2645             :  * @ie: Pointer to IE data (starting from id)
    2646             :  * @len: IE length
    2647             :  * Returns: 0 on success, -1 on failure
    2648             :  *
    2649             :  * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
    2650             :  * Request frame. The IE will be used to override the default value generated
    2651             :  * with wpa_sm_set_assoc_wpa_ie_default().
    2652             :  */
    2653        3259 : int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2654             : {
    2655        3259 :         if (sm == NULL)
    2656           0 :                 return -1;
    2657             : 
    2658        3259 :         os_free(sm->assoc_wpa_ie);
    2659        3259 :         if (ie == NULL || len == 0) {
    2660        1354 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2661             :                         "WPA: clearing own WPA/RSN IE");
    2662        1354 :                 sm->assoc_wpa_ie = NULL;
    2663        1354 :                 sm->assoc_wpa_ie_len = 0;
    2664             :         } else {
    2665        1905 :                 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
    2666        1905 :                 sm->assoc_wpa_ie = os_malloc(len);
    2667        1905 :                 if (sm->assoc_wpa_ie == NULL)
    2668           0 :                         return -1;
    2669             : 
    2670        1905 :                 os_memcpy(sm->assoc_wpa_ie, ie, len);
    2671        1905 :                 sm->assoc_wpa_ie_len = len;
    2672             :         }
    2673             : 
    2674        3259 :         return 0;
    2675             : }
    2676             : 
    2677             : 
    2678             : /**
    2679             :  * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
    2680             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2681             :  * @ie: Pointer to IE data (starting from id)
    2682             :  * @len: IE length
    2683             :  * Returns: 0 on success, -1 on failure
    2684             :  *
    2685             :  * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
    2686             :  * frame.
    2687             :  */
    2688        2586 : int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2689             : {
    2690        2586 :         if (sm == NULL)
    2691           0 :                 return -1;
    2692             : 
    2693        2586 :         os_free(sm->ap_wpa_ie);
    2694        2586 :         if (ie == NULL || len == 0) {
    2695        2536 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2696             :                         "WPA: clearing AP WPA IE");
    2697        2536 :                 sm->ap_wpa_ie = NULL;
    2698        2536 :                 sm->ap_wpa_ie_len = 0;
    2699             :         } else {
    2700          50 :                 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
    2701          50 :                 sm->ap_wpa_ie = os_malloc(len);
    2702          50 :                 if (sm->ap_wpa_ie == NULL)
    2703           0 :                         return -1;
    2704             : 
    2705          50 :                 os_memcpy(sm->ap_wpa_ie, ie, len);
    2706          50 :                 sm->ap_wpa_ie_len = len;
    2707             :         }
    2708             : 
    2709        2586 :         return 0;
    2710             : }
    2711             : 
    2712             : 
    2713             : /**
    2714             :  * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
    2715             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2716             :  * @ie: Pointer to IE data (starting from id)
    2717             :  * @len: IE length
    2718             :  * Returns: 0 on success, -1 on failure
    2719             :  *
    2720             :  * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
    2721             :  * frame.
    2722             :  */
    2723        2598 : int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2724             : {
    2725        2598 :         if (sm == NULL)
    2726           0 :                 return -1;
    2727             : 
    2728        2598 :         os_free(sm->ap_rsn_ie);
    2729        2598 :         if (ie == NULL || len == 0) {
    2730         717 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2731             :                         "WPA: clearing AP RSN IE");
    2732         717 :                 sm->ap_rsn_ie = NULL;
    2733         717 :                 sm->ap_rsn_ie_len = 0;
    2734             :         } else {
    2735        1881 :                 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
    2736        1881 :                 sm->ap_rsn_ie = os_malloc(len);
    2737        1881 :                 if (sm->ap_rsn_ie == NULL)
    2738           1 :                         return -1;
    2739             : 
    2740        1880 :                 os_memcpy(sm->ap_rsn_ie, ie, len);
    2741        1880 :                 sm->ap_rsn_ie_len = len;
    2742             :         }
    2743             : 
    2744        2597 :         return 0;
    2745             : }
    2746             : 
    2747             : 
    2748             : /**
    2749             :  * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
    2750             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2751             :  * @data: Pointer to data area for parsing results
    2752             :  * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
    2753             :  *
    2754             :  * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
    2755             :  * parsed data into data.
    2756             :  */
    2757          22 : int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
    2758             : {
    2759          22 :         if (sm == NULL)
    2760           0 :                 return -1;
    2761             : 
    2762          22 :         if (sm->assoc_wpa_ie == NULL) {
    2763          14 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2764             :                         "WPA: No WPA/RSN IE available from association info");
    2765          14 :                 return -1;
    2766             :         }
    2767           8 :         if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
    2768           0 :                 return -2;
    2769           8 :         return 0;
    2770             : }
    2771             : 
    2772             : 
    2773         149 : int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
    2774             : {
    2775         149 :         return pmksa_cache_list(sm->pmksa, buf, len);
    2776             : }
    2777             : 
    2778             : 
    2779        2717 : void wpa_sm_drop_sa(struct wpa_sm *sm)
    2780             : {
    2781        2717 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
    2782        2717 :         sm->ptk_set = 0;
    2783        2717 :         sm->tptk_set = 0;
    2784        2717 :         os_memset(sm->pmk, 0, sizeof(sm->pmk));
    2785        2717 :         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
    2786        2717 :         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    2787             : #ifdef CONFIG_IEEE80211R
    2788        2717 :         os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
    2789        2717 :         os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
    2790        2717 :         os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
    2791             : #endif /* CONFIG_IEEE80211R */
    2792        2717 : }
    2793             : 
    2794             : 
    2795         113 : int wpa_sm_has_ptk(struct wpa_sm *sm)
    2796             : {
    2797         113 :         if (sm == NULL)
    2798           0 :                 return 0;
    2799         113 :         return sm->ptk_set;
    2800             : }
    2801             : 
    2802             : 
    2803           0 : void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
    2804             : {
    2805           0 :         os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
    2806           0 : }
    2807             : 
    2808             : 
    2809       14396 : void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
    2810             : {
    2811       14396 :         pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
    2812       14396 : }
    2813             : 
    2814             : 
    2815             : #ifdef CONFIG_WNM
    2816           2 : int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
    2817             : {
    2818             :         u16 keyinfo;
    2819             :         u8 keylen;  /* plaintext key len */
    2820             :         u8 *key_rsc;
    2821             : 
    2822           2 :         if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
    2823             :                 struct wpa_gtk_data gd;
    2824             : 
    2825           1 :                 os_memset(&gd, 0, sizeof(gd));
    2826           1 :                 keylen = wpa_cipher_key_len(sm->group_cipher);
    2827           1 :                 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
    2828           1 :                 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
    2829           1 :                 if (gd.alg == WPA_ALG_NONE) {
    2830           0 :                         wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
    2831           0 :                         return -1;
    2832             :                 }
    2833             : 
    2834           1 :                 key_rsc = buf + 5;
    2835           1 :                 keyinfo = WPA_GET_LE16(buf + 2);
    2836           1 :                 gd.gtk_len = keylen;
    2837           1 :                 if (gd.gtk_len != buf[4]) {
    2838           0 :                         wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
    2839           0 :                                    gd.gtk_len, buf[4]);
    2840           0 :                         return -1;
    2841             :                 }
    2842           1 :                 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
    2843           1 :                 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
    2844           1 :                          sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
    2845             : 
    2846           1 :                 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
    2847             : 
    2848           1 :                 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
    2849           1 :                                 gd.gtk, gd.gtk_len);
    2850           1 :                 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
    2851           0 :                         os_memset(&gd, 0, sizeof(gd));
    2852           0 :                         wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
    2853             :                                    "WNM mode");
    2854           0 :                         return -1;
    2855             :                 }
    2856           1 :                 os_memset(&gd, 0, sizeof(gd));
    2857             : #ifdef CONFIG_IEEE80211W
    2858           1 :         } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
    2859             :                 struct wpa_igtk_kde igd;
    2860             :                 u16 keyidx;
    2861             : 
    2862           1 :                 os_memset(&igd, 0, sizeof(igd));
    2863           1 :                 keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
    2864           1 :                 os_memcpy(igd.keyid, buf + 2, 2);
    2865           1 :                 os_memcpy(igd.pn, buf + 4, 6);
    2866             : 
    2867           1 :                 keyidx = WPA_GET_LE16(igd.keyid);
    2868           1 :                 os_memcpy(igd.igtk, buf + 10, keylen);
    2869             : 
    2870           1 :                 wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
    2871             :                                 igd.igtk, keylen);
    2872           1 :                 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
    2873             :                                    broadcast_ether_addr,
    2874             :                                    keyidx, 0, igd.pn, sizeof(igd.pn),
    2875             :                                    igd.igtk, keylen) < 0) {
    2876           0 :                         wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
    2877             :                                    "WNM mode");
    2878           0 :                         os_memset(&igd, 0, sizeof(igd));
    2879           0 :                         return -1;
    2880             :                 }
    2881           1 :                 os_memset(&igd, 0, sizeof(igd));
    2882             : #endif /* CONFIG_IEEE80211W */
    2883             :         } else {
    2884           0 :                 wpa_printf(MSG_DEBUG, "Unknown element id");
    2885           0 :                 return -1;
    2886             :         }
    2887             : 
    2888           2 :         return 0;
    2889             : }
    2890             : #endif /* CONFIG_WNM */
    2891             : 
    2892             : 
    2893             : #ifdef CONFIG_PEERKEY
    2894          18 : int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
    2895             :                             const u8 *buf, size_t len)
    2896             : {
    2897             :         struct wpa_peerkey *peerkey;
    2898             : 
    2899          24 :         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
    2900          10 :                 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
    2901           4 :                         break;
    2902             :         }
    2903             : 
    2904          18 :         if (!peerkey)
    2905          14 :                 return 0;
    2906             : 
    2907           4 :         wpa_sm_rx_eapol(sm, src_addr, buf, len);
    2908             : 
    2909           4 :         return 1;
    2910             : }
    2911             : #endif /* CONFIG_PEERKEY */
    2912             : 
    2913             : 
    2914             : #ifdef CONFIG_P2P
    2915             : 
    2916         189 : int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
    2917             : {
    2918         189 :         if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
    2919         117 :                 return -1;
    2920          72 :         os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
    2921          72 :         return 0;
    2922             : }
    2923             : 
    2924             : #endif /* CONFIG_P2P */
    2925             : 
    2926             : 
    2927           0 : void wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter)
    2928             : {
    2929           0 :         if (rx_replay_counter == NULL)
    2930           0 :                 return;
    2931             : 
    2932           0 :         os_memcpy(sm->rx_replay_counter, rx_replay_counter,
    2933             :                   WPA_REPLAY_COUNTER_LEN);
    2934           0 :         sm->rx_replay_counter_set = 1;
    2935           0 :         wpa_printf(MSG_DEBUG, "Updated key replay counter");
    2936             : }
    2937             : 
    2938             : 
    2939           0 : void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
    2940             :                             const u8 *ptk_kck, size_t ptk_kck_len,
    2941             :                             const u8 *ptk_kek, size_t ptk_kek_len)
    2942             : {
    2943           0 :         if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) {
    2944           0 :                 os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len);
    2945           0 :                 sm->ptk.kck_len = ptk_kck_len;
    2946           0 :                 wpa_printf(MSG_DEBUG, "Updated PTK KCK");
    2947             :         }
    2948           0 :         if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) {
    2949           0 :                 os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len);
    2950           0 :                 sm->ptk.kek_len = ptk_kek_len;
    2951           0 :                 wpa_printf(MSG_DEBUG, "Updated PTK KEK");
    2952             :         }
    2953           0 :         sm->ptk_set = 1;
    2954           0 : }

Generated by: LCOV version 1.10