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 1401264779 Lines: 963 1248 77.2 %
Date: 2014-05-28 Functions: 61 63 96.8 %

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

Generated by: LCOV version 1.10