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 1422976643 Lines: 1027 1331 77.2 %
Date: 2015-02-03 Functions: 62 66 93.9 %

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

Generated by: LCOV version 1.10