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 1401872338 Lines: 963 1248 77.2 %
Date: 2014-06-04 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        1386 : 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        1386 :         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        2770 :         if (key_mic &&
      59        1384 :             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        1386 :         wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, 16);
      66        1386 :         wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, 16);
      67        1386 :         wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
      68        1386 :         wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
      69        1386 :         eapol_sm_notify_tx_eapol_key(sm->eapol);
      70             : out:
      71        1386 :         os_free(msg);
      72        1386 : }
      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           1 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
     104             :                         "Failed to read BSSID for EAPOL-Key request");
     105           1 :                 return;
     106             :         }
     107             : 
     108           7 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
     109             :                                   sizeof(*reply), &rlen, (void *) &reply);
     110           7 :         if (rbuf == NULL)
     111           0 :                 return;
     112             : 
     113          11 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
     114           4 :                        sm->proto == WPA_PROTO_OSEN) ?
     115             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
     116           7 :         key_info = WPA_KEY_INFO_REQUEST | ver;
     117           7 :         if (sm->ptk_set)
     118           6 :                 key_info |= WPA_KEY_INFO_MIC;
     119           7 :         if (error)
     120           2 :                 key_info |= WPA_KEY_INFO_ERROR;
     121           7 :         if (pairwise)
     122           6 :                 key_info |= WPA_KEY_INFO_KEY_TYPE;
     123           7 :         WPA_PUT_BE16(reply->key_info, key_info);
     124           7 :         WPA_PUT_BE16(reply->key_length, 0);
     125           7 :         os_memcpy(reply->replay_counter, sm->request_counter,
     126             :                   WPA_REPLAY_COUNTER_LEN);
     127           7 :         inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
     128             : 
     129           7 :         WPA_PUT_BE16(reply->key_data_length, 0);
     130             : 
     131           7 :         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          13 :         wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
     136           7 :                            rbuf, rlen, key_info & WPA_KEY_INFO_MIC ?
     137           6 :                            reply->key_mic : NULL);
     138             : }
     139             : 
     140             : 
     141         685 : static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
     142             :                                   const unsigned char *src_addr,
     143             :                                   const u8 *pmkid)
     144             : {
     145         685 :         int abort_cached = 0;
     146             : 
     147         685 :         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         278 :                 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
     153             :                                                 NULL);
     154         278 :                 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         275 :                         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     159             :                                 "RSN: no matching PMKID found");
     160         275 :                         abort_cached = 1;
     161             :                 }
     162             :         }
     163             : 
     164         696 :         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         675 :         } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
     175             :                 int res, pmk_len;
     176         280 :                 pmk_len = PMK_LEN;
     177         280 :                 res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
     178         280 :                 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         280 :                         if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
     189             :                         {
     190         280 :                                 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
     191         280 :                                 sm->xxkey_len = PMK_LEN;
     192         280 :                                 os_memset(buf, 0, sizeof(buf));
     193             :                         }
     194             : #endif /* CONFIG_IEEE80211R */
     195             :                 }
     196         280 :                 if (res == 0) {
     197         280 :                         struct rsn_pmksa_cache_entry *sa = NULL;
     198         560 :                         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
     199         280 :                                         "machines", sm->pmk, pmk_len);
     200         280 :                         sm->pmk_len = pmk_len;
     201         556 :                         if (sm->proto == WPA_PROTO_RSN &&
     202         276 :                             !wpa_key_mgmt_ft(sm->key_mgmt)) {
     203         819 :                                 sa = pmksa_cache_add(sm->pmksa,
     204         273 :                                                      sm->pmk, pmk_len,
     205         273 :                                                      src_addr, sm->own_addr,
     206             :                                                      sm->network_ctx,
     207         273 :                                                      sm->key_mgmt);
     208             :                         }
     209         556 :                         if (!sm->cur_pmksa && pmkid &&
     210         276 :                             pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
     211             :                         {
     212         272 :                                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     213             :                                         "RSN: the new PMK matches with the "
     214             :                                         "PMKID");
     215         272 :                                 abort_cached = 0;
     216             :                         }
     217             : 
     218         280 :                         if (!sm->cur_pmksa)
     219         280 :                                 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         689 :         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         684 :         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         685 : 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         685 :         u8 *rsn_ie_buf = NULL;
     285             : 
     286         685 :         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         685 :         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          19 :                 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
     301          19 :                                        sm->assoc_resp_ies_len);
     302          19 :                 if (rsn_ie_buf == NULL)
     303           0 :                         return -1;
     304          19 :                 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
     305          19 :                 res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len,
     306          19 :                                        sm->pmk_r1_name);
     307          19 :                 if (res < 0) {
     308           0 :                         os_free(rsn_ie_buf);
     309           0 :                         return -1;
     310             :                 }
     311          19 :                 wpa_ie_len += res;
     312             : 
     313          19 :                 if (sm->assoc_resp_ies) {
     314          19 :                         os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
     315             :                                   sm->assoc_resp_ies_len);
     316          19 :                         wpa_ie_len += sm->assoc_resp_ies_len;
     317             :                 }
     318             : 
     319          19 :                 wpa_ie = rsn_ie_buf;
     320             :         }
     321             : #endif /* CONFIG_IEEE80211R */
     322             : 
     323         685 :         wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
     324             : 
     325         685 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
     326             :                                   NULL, sizeof(*reply) + wpa_ie_len,
     327             :                                   &rlen, (void *) &reply);
     328         685 :         if (rbuf == NULL) {
     329           0 :                 os_free(rsn_ie_buf);
     330           0 :                 return -1;
     331             :         }
     332             : 
     333         704 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
     334          19 :                        sm->proto == WPA_PROTO_OSEN) ?
     335             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
     336         685 :         WPA_PUT_BE16(reply->key_info,
     337             :                      ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
     338         685 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
     339         668 :                 WPA_PUT_BE16(reply->key_length, 0);
     340             :         else
     341          17 :                 os_memcpy(reply->key_length, key->key_length, 2);
     342         685 :         os_memcpy(reply->replay_counter, key->replay_counter,
     343             :                   WPA_REPLAY_COUNTER_LEN);
     344         685 :         wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
     345             :                     WPA_REPLAY_COUNTER_LEN);
     346             : 
     347         685 :         WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
     348         685 :         os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
     349         685 :         os_free(rsn_ie_buf);
     350             : 
     351         685 :         os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
     352             : 
     353         685 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
     354         685 :         wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
     355         685 :                            rbuf, rlen, reply->key_mic);
     356             : 
     357         685 :         return 0;
     358             : }
     359             : 
     360             : 
     361         684 : 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         684 :         size_t ptk_len = wpa_cipher_key_len(sm->pairwise_cipher) + 32;
     366             : #ifdef CONFIG_IEEE80211R
     367         684 :         if (wpa_key_mgmt_ft(sm->key_mgmt))
     368          19 :                 return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len);
     369             : #endif /* CONFIG_IEEE80211R */
     370             : 
     371        1330 :         wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
     372         665 :                        sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
     373             :                        (u8 *) ptk, ptk_len,
     374         665 :                        wpa_key_mgmt_sha256(sm->key_mgmt));
     375         665 :         return 0;
     376             : }
     377             : 
     378             : 
     379         685 : 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         685 :         u8 *kde, *kde_buf = NULL;
     388             :         size_t kde_len;
     389             : 
     390         685 :         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         685 :         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
     397         685 :         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         685 :         os_memset(&ie, 0, sizeof(ie));
     401             : 
     402         685 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
     403             :                 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
     404         668 :                 const u8 *_buf = (const u8 *) (key + 1);
     405         668 :                 size_t len = WPA_GET_BE16(key->key_data_length);
     406         668 :                 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len);
     407         668 :                 if (wpa_supplicant_parse_ies(_buf, len, &ie) < 0)
     408           0 :                         goto failed;
     409         668 :                 if (ie.pmkid) {
     410         286 :                         wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
     411         286 :                                     "Authenticator", ie.pmkid, PMKID_LEN);
     412             :                 }
     413             :         }
     414             : 
     415         685 :         res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
     416         685 :         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         684 :         if (res)
     422           0 :                 goto failed;
     423             : 
     424         684 :         if (sm->renew_snonce) {
     425         665 :                 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         665 :                 sm->renew_snonce = 0;
     431         665 :                 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
     432         665 :                             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         684 :         ptk = &sm->tptk;
     438         684 :         wpa_derive_ptk(sm, src_addr, key, ptk);
     439         684 :         if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
     440             :                 u8 buf[8];
     441             :                 /* Supplicant: swap tx/rx Mic keys */
     442          18 :                 os_memcpy(buf, ptk->u.auth.tx_mic_key, 8);
     443          18 :                 os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
     444          18 :                 os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);
     445          18 :                 os_memset(buf, 0, sizeof(buf));
     446             :         }
     447         684 :         sm->tptk_set = 1;
     448             : 
     449         684 :         kde = sm->assoc_wpa_ie;
     450         684 :         kde_len = sm->assoc_wpa_ie_len;
     451             : 
     452             : #ifdef CONFIG_P2P
     453         684 :         if (sm->p2p) {
     454         145 :                 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
     455         145 :                 if (kde_buf) {
     456             :                         u8 *pos;
     457         145 :                         wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
     458             :                                    "into EAPOL-Key 2/4");
     459         145 :                         os_memcpy(kde_buf, kde, kde_len);
     460         145 :                         kde = kde_buf;
     461         145 :                         pos = kde + kde_len;
     462         145 :                         *pos++ = WLAN_EID_VENDOR_SPECIFIC;
     463         145 :                         *pos++ = RSN_SELECTOR_LEN + 1;
     464         145 :                         RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
     465         145 :                         pos += RSN_SELECTOR_LEN;
     466         145 :                         *pos++ = 0x01;
     467         145 :                         kde_len = pos - kde;
     468             :                 }
     469             :         }
     470             : #endif /* CONFIG_P2P */
     471             : 
     472         684 :         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         684 :         os_free(kde_buf);
     477         684 :         os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
     478         684 :         return;
     479             : 
     480             : failed:
     481           0 :         os_free(kde_buf);
     482           0 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
     483             : }
     484             : 
     485             : 
     486         855 : static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
     487             : {
     488         855 :         struct wpa_sm *sm = eloop_ctx;
     489         855 :         rsn_preauth_candidate_process(sm);
     490         855 : }
     491             : 
     492             : 
     493         879 : static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
     494             :                                             const u8 *addr, int secure)
     495             : {
     496        7032 :         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     497             :                 "WPA: Key negotiation completed with "
     498        5274 :                 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
     499         879 :                 wpa_cipher_txt(sm->pairwise_cipher),
     500         879 :                 wpa_cipher_txt(sm->group_cipher));
     501         879 :         wpa_sm_cancel_auth_timeout(sm);
     502         879 :         wpa_sm_set_state(sm, WPA_COMPLETED);
     503             : 
     504         879 :         if (secure) {
     505         879 :                 wpa_sm_mlme_setprotection(
     506             :                         sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
     507             :                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
     508         879 :                 eapol_sm_notify_portValid(sm->eapol, TRUE);
     509         879 :                 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
     510         586 :                         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         879 :                 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
     519             :         }
     520             : 
     521         879 :         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         879 :         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
     530             :                 /* Prepare for the next transition */
     531         240 :                 wpa_ft_prepare_auth_request(sm, NULL);
     532             :         }
     533             : #endif /* CONFIG_IEEE80211R */
     534         879 : }
     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         658 : 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         658 :         u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
     552             : 
     553         658 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
     554             :                 "WPA: Installing PTK to the driver");
     555             : 
     556         658 :         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         658 :         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         658 :         alg = wpa_cipher_to_alg(sm->pairwise_cipher);
     570         658 :         keylen = wpa_cipher_key_len(sm->pairwise_cipher);
     571         658 :         rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
     572             : 
     573         658 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
     574         641 :                 key_rsc = null_rsc;
     575             :         } else {
     576          17 :                 key_rsc = key->key_rsc;
     577          17 :                 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
     578             :         }
     579             : 
     580        1316 :         if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
     581         658 :                            (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         658 :         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         658 :         return 0;
     596             : }
     597             : 
     598             : 
     599         665 : 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         665 :         *alg = wpa_cipher_to_alg(group_cipher);
     608         665 :         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         665 :         *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
     615             : 
     616         665 :         klen = wpa_cipher_key_len(group_cipher);
     617         665 :         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         665 :         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         666 : static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
     636             :                                       const struct wpa_gtk_data *gd,
     637             :                                       const u8 *key_rsc)
     638             : {
     639         666 :         const u8 *_gtk = gd->gtk;
     640             :         u8 gtk_buf[32];
     641             : 
     642         666 :         wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
     643         666 :         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         666 :         wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
     647         666 :         if (sm->group_cipher == WPA_CIPHER_TKIP) {
     648             :                 /* Swap Tx/Rx keys for Michael MIC */
     649          38 :                 os_memcpy(gtk_buf, gd->gtk, 16);
     650          38 :                 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
     651          38 :                 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
     652          38 :                 _gtk = gtk_buf;
     653             :         }
     654         666 :         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        1332 :         } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
     665         666 :                                   gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
     666         666 :                                   _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         666 :         os_memset(gtk_buf, 0, sizeof(gtk_buf));
     675             : 
     676         666 :         return 0;
     677             : }
     678             : 
     679             : 
     680         666 : static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
     681             :                                                 int tx)
     682             : {
     683         666 :         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         666 :         return tx;
     695             : }
     696             : 
     697             : 
     698         639 : 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         639 :         os_memset(&gd, 0, sizeof(gd));
     714         639 :         wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
     715             :                         gtk, gtk_len);
     716             : 
     717         639 :         if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
     718           0 :                 return -1;
     719             : 
     720         639 :         gd.keyidx = gtk[0] & 0x3;
     721         639 :         gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
     722         639 :                                                      !!(gtk[0] & BIT(2)));
     723         639 :         gtk += 2;
     724         639 :         gtk_len -= 2;
     725             : 
     726         639 :         os_memcpy(gd.gtk, gtk, gtk_len);
     727         639 :         gd.gtk_len = gtk_len;
     728             : 
     729        1278 :         if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
     730         639 :             (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
     731             :                                                gtk_len, gtk_len,
     732         639 :                                                &gd.key_rsc_len, &gd.alg) ||
     733         639 :              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         639 :         os_memset(&gd, 0, sizeof(gd));
     740             : 
     741         639 :         wpa_supplicant_key_neg_complete(sm, sm->bssid,
     742             :                                         key_info & WPA_KEY_INFO_SECURE);
     743         639 :         return 0;
     744             : }
     745             : 
     746             : 
     747         666 : static int ieee80211w_set_keys(struct wpa_sm *sm,
     748             :                                struct wpa_eapol_ie_parse *ie)
     749             : {
     750             : #ifdef CONFIG_IEEE80211W
     751         666 :         if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
     752         638 :                 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          19 : 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          19 :         mdie = (struct rsn_mdie *) (ie->mdie + 2);
     838          38 :         if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
     839          19 :             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          38 :         if (assoc_resp_mdie &&
     847          38 :             (assoc_resp_mdie[1] != ie->mdie[1] ||
     848          19 :              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          19 :         return 0;
     858             : }
     859             : 
     860             : 
     861          19 : 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          19 :         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          19 :         if (assoc_resp_ftie == NULL)
     873           0 :                 return 0;
     874             : 
     875          38 :         if (assoc_resp_ftie[1] != ie->ftie[1] ||
     876          19 :             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          19 :         return 0;
     886             : }
     887             : 
     888             : 
     889          19 : 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          19 :         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          38 :         if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
     903          38 :             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          19 :         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          19 :         return 0;
     921             : }
     922             : 
     923             : 
     924          19 : 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          19 :         const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
     929             : 
     930          19 :         if (sm->assoc_resp_ies) {
     931          19 :                 pos = sm->assoc_resp_ies;
     932          19 :                 end = pos + sm->assoc_resp_ies_len;
     933          76 :                 while (pos + 2 < end) {
     934          38 :                         if (pos + 2 + pos[1] > end)
     935           0 :                                 break;
     936          38 :                         switch (*pos) {
     937             :                         case WLAN_EID_MOBILITY_DOMAIN:
     938          19 :                                 mdie = pos;
     939          19 :                                 break;
     940             :                         case WLAN_EID_FAST_BSS_TRANSITION:
     941          19 :                                 ftie = pos;
     942          19 :                                 break;
     943             :                         }
     944          38 :                         pos += 2 + pos[1];
     945             :                 }
     946             :         }
     947             : 
     948          38 :         if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
     949          38 :             ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
     950          19 :             ft_validate_rsnie(sm, src_addr, ie) < 0)
     951           0 :                 return -1;
     952             : 
     953          19 :         return 0;
     954             : }
     955             : 
     956             : #endif /* CONFIG_IEEE80211R */
     957             : 
     958             : 
     959         658 : 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         658 :         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         660 :         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         693 :         if ((ie->wpa_ie && sm->ap_wpa_ie &&
     988          70 :              (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
     989         693 :               os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
     990        1936 :             (ie->rsn_ie && sm->ap_rsn_ie &&
     991        1278 :              wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
     992         639 :                                 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         675 :         if (sm->proto == WPA_PROTO_WPA &&
    1002          17 :             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         677 :         if (wpa_key_mgmt_ft(sm->key_mgmt) &&
    1014          19 :             wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
    1015           0 :                 return -1;
    1016             : #endif /* CONFIG_IEEE80211R */
    1017             : 
    1018         658 :         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         659 : 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         659 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
    1042             :                                   sizeof(*reply), &rlen, (void *) &reply);
    1043         659 :         if (rbuf == NULL)
    1044           0 :                 return -1;
    1045             : 
    1046         678 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
    1047          19 :                        sm->proto == WPA_PROTO_OSEN) ?
    1048             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
    1049         659 :         key_info &= WPA_KEY_INFO_SECURE;
    1050         659 :         key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
    1051         659 :         WPA_PUT_BE16(reply->key_info, key_info);
    1052         659 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
    1053         642 :                 WPA_PUT_BE16(reply->key_length, 0);
    1054             :         else
    1055          17 :                 os_memcpy(reply->key_length, key->key_length, 2);
    1056         659 :         os_memcpy(reply->replay_counter, key->replay_counter,
    1057             :                   WPA_REPLAY_COUNTER_LEN);
    1058             : 
    1059         659 :         WPA_PUT_BE16(reply->key_data_length, 0);
    1060             : 
    1061         659 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
    1062         659 :         wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
    1063         659 :                            rbuf, rlen, reply->key_mic);
    1064             : 
    1065         659 :         return 0;
    1066             : }
    1067             : 
    1068             : 
    1069         658 : 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         658 :         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
    1078         658 :         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         658 :         key_info = WPA_GET_BE16(key->key_info);
    1082             : 
    1083         658 :         pos = (const u8 *) (key + 1);
    1084         658 :         len = WPA_GET_BE16(key->key_data_length);
    1085         658 :         wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);
    1086         658 :         if (wpa_supplicant_parse_ies(pos, len, &ie) < 0)
    1087           0 :                 goto failed;
    1088         658 :         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         658 :         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         688 :         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         658 :         if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
    1112           0 :                 goto failed;
    1113             : 
    1114         658 :         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         658 :         keylen = WPA_GET_BE16(key->key_length);
    1123         658 :         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         658 :         if (ie.ip_addr_alloc) {
    1133          85 :                 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
    1134          85 :                 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
    1135          85 :                             sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
    1136             :         }
    1137             : #endif /* CONFIG_P2P */
    1138             : 
    1139         658 :         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         658 :         sm->renew_snonce = 1;
    1148             : 
    1149         658 :         if (key_info & WPA_KEY_INFO_INSTALL) {
    1150         658 :                 if (wpa_supplicant_install_ptk(sm, key))
    1151           0 :                         goto failed;
    1152             :         }
    1153             : 
    1154         658 :         if (key_info & WPA_KEY_INFO_SECURE) {
    1155         641 :                 wpa_sm_mlme_setprotection(
    1156         641 :                         sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
    1157             :                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
    1158         641 :                 eapol_sm_notify_portValid(sm->eapol, TRUE);
    1159             :         }
    1160         658 :         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
    1161             : 
    1162         658 :         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        1295 :         } else if (ie.gtk &&
    1166         639 :             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         658 :         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         658 :         if (ie.gtk)
    1180         641 :                 wpa_sm_set_rekey_offload(sm);
    1181             : 
    1182        1316 :         return;
    1183             : 
    1184             : failed:
    1185           0 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    1186             : }
    1187             : 
    1188             : 
    1189           8 : 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           8 :         wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
    1199           8 :         if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
    1200           0 :                 return -1;
    1201           8 :         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           8 :         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           8 :         maxkeylen = gd->gtk_len = ie.gtk_len - 2;
    1212             : 
    1213           8 :         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          16 :         wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",
    1219           8 :                     ie.gtk, ie.gtk_len);
    1220           8 :         gd->keyidx = ie.gtk[0] & 0x3;
    1221           8 :         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
    1222           8 :                                                       !!(ie.gtk[0] & BIT(2)));
    1223           8 :         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           8 :         os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
    1230             : 
    1231           8 :         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           8 :         return 0;
    1236             : }
    1237             : 
    1238             : 
    1239          18 : 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          18 :         gd->gtk_len = WPA_GET_BE16(key->key_length);
    1248          18 :         maxkeylen = keydatalen;
    1249          18 :         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          18 :         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          18 :         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          18 :         gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
    1272             :                 WPA_KEY_INFO_KEY_INDEX_SHIFT;
    1273          18 :         if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
    1274             :                 u8 ek[32];
    1275          17 :                 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          17 :                 os_memcpy(ek, key->key_iv, 16);
    1282          17 :                 os_memcpy(ek + 16, sm->ptk.kek, 16);
    1283          17 :                 os_memcpy(gd->gtk, key + 1, keydatalen);
    1284          17 :                 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          17 :                 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          18 :         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
    1319          18 :                 sm, !!(key_info & WPA_KEY_INFO_TXRX));
    1320          18 :         return 0;
    1321             : }
    1322             : 
    1323             : 
    1324          26 : 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          26 :         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
    1333             :                                   sizeof(*reply), &rlen, (void *) &reply);
    1334          26 :         if (rbuf == NULL)
    1335           0 :                 return -1;
    1336             : 
    1337          44 :         reply->type = (sm->proto == WPA_PROTO_RSN ||
    1338          18 :                        sm->proto == WPA_PROTO_OSEN) ?
    1339             :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
    1340          26 :         key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
    1341          26 :         key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
    1342          26 :         WPA_PUT_BE16(reply->key_info, key_info);
    1343          26 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
    1344           8 :                 WPA_PUT_BE16(reply->key_length, 0);
    1345             :         else
    1346          18 :                 os_memcpy(reply->key_length, key->key_length, 2);
    1347          26 :         os_memcpy(reply->replay_counter, key->replay_counter,
    1348             :                   WPA_REPLAY_COUNTER_LEN);
    1349             : 
    1350          26 :         WPA_PUT_BE16(reply->key_data_length, 0);
    1351             : 
    1352          26 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
    1353          26 :         wpa_eapol_key_send(sm, sm->ptk.kck, ver, sm->bssid, ETH_P_EAPOL,
    1354          26 :                            rbuf, rlen, reply->key_mic);
    1355             : 
    1356          26 :         return 0;
    1357             : }
    1358             : 
    1359             : 
    1360          26 : 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          26 :         os_memset(&gd, 0, sizeof(gd));
    1370             : 
    1371          26 :         rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
    1372          26 :         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          26 :         key_info = WPA_GET_BE16(key->key_info);
    1376          26 :         keydatalen = WPA_GET_BE16(key->key_data_length);
    1377             : 
    1378          26 :         if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
    1379           8 :                 ret = wpa_supplicant_process_1_of_2_rsn(sm,
    1380             :                                                         (const u8 *) (key + 1),
    1381             :                                                         keydatalen, key_info,
    1382             :                                                         &gd);
    1383             :         } else {
    1384          18 :                 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, keydatalen,
    1385             :                                                         key_info, extra_len,
    1386             :                                                         ver, &gd);
    1387             :         }
    1388             : 
    1389          26 :         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
    1390             : 
    1391          26 :         if (ret)
    1392           0 :                 goto failed;
    1393             : 
    1394          52 :         if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
    1395          26 :             wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
    1396             :                 goto failed;
    1397             : 
    1398          26 :         if (rekey) {
    1399          63 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
    1400             :                         "completed with " MACSTR " [GTK=%s]",
    1401          63 :                         MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
    1402           9 :                 wpa_sm_cancel_auth_timeout(sm);
    1403           9 :                 wpa_sm_set_state(sm, WPA_COMPLETED);
    1404             :         } else {
    1405          17 :                 wpa_supplicant_key_neg_complete(sm, sm->bssid,
    1406             :                                                 key_info &
    1407             :                                                 WPA_KEY_INFO_SECURE);
    1408             :         }
    1409             : 
    1410          26 :         wpa_sm_set_rekey_offload(sm);
    1411             : 
    1412          52 :         return;
    1413             : 
    1414             : failed:
    1415           0 :         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    1416             : }
    1417             : 
    1418             : 
    1419         692 : 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         692 :         int ok = 0;
    1426             : 
    1427         692 :         os_memcpy(mic, key->key_mic, 16);
    1428         692 :         if (sm->tptk_set) {
    1429         658 :                 os_memset(key->key_mic, 0, 16);
    1430         658 :                 wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
    1431         658 :                                   key->key_mic);
    1432         658 :                 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         658 :                         ok = 1;
    1438         658 :                         sm->tptk_set = 0;
    1439         658 :                         sm->ptk_set = 1;
    1440         658 :                         os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
    1441         658 :                         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    1442             :                 }
    1443             :         }
    1444             : 
    1445         692 :         if (!ok && sm->ptk_set) {
    1446          34 :                 os_memset(key->key_mic, 0, 16);
    1447          34 :                 wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
    1448          34 :                                   key->key_mic);
    1449          34 :                 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          34 :                 ok = 1;
    1456             :         }
    1457             : 
    1458         692 :         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         692 :         os_memcpy(sm->rx_replay_counter, key->replay_counter,
    1466             :                   WPA_REPLAY_COUNTER_LEN);
    1467         692 :         sm->rx_replay_counter_set = 1;
    1468         692 :         return 0;
    1469             : }
    1470             : 
    1471             : 
    1472             : /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
    1473         651 : static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
    1474             :                                            struct wpa_eapol_key *key, u16 ver)
    1475             : {
    1476         651 :         u16 keydatalen = WPA_GET_BE16(key->key_data_length);
    1477             : 
    1478         651 :         wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
    1479             :                     (u8 *) (key + 1), keydatalen);
    1480         651 :         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         651 :         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         649 :         } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
    1501           2 :                    ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
    1502         651 :                    sm->key_mgmt == WPA_KEY_MGMT_OSEN) {
    1503             :                 u8 *buf;
    1504         649 :                 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         649 :                 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
    1511         649 :                 buf = os_malloc(keydatalen);
    1512         649 :                 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         649 :                 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         649 :                 os_memcpy(key + 1, buf, keydatalen);
    1526         649 :                 os_free(buf);
    1527         649 :                 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         651 :         wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
    1534             :                         (u8 *) (key + 1), keydatalen);
    1535         651 :         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        1381 : 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        1381 :         u16 key_info = WPA_GET_BE16(key->key_info);
    1558             : 
    1559        1381 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "  EAPOL-Key type=%d", key->type);
    1560        1381 :         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        1381 :         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        1381 :         wpa_hexdump(MSG_DEBUG, "  replay_counter",
    1579        1381 :                     key->replay_counter, WPA_REPLAY_COUNTER_LEN);
    1580        1381 :         wpa_hexdump(MSG_DEBUG, "  key_nonce", key->key_nonce, WPA_NONCE_LEN);
    1581        1381 :         wpa_hexdump(MSG_DEBUG, "  key_iv", key->key_iv, 16);
    1582        1381 :         wpa_hexdump(MSG_DEBUG, "  key_rsc", key->key_rsc, 8);
    1583        1381 :         wpa_hexdump(MSG_DEBUG, "  key_id (reserved)", key->key_id, 8);
    1584        1381 :         wpa_hexdump(MSG_DEBUG, "  key_mic", key->key_mic, 16);
    1585             : #endif /* CONFIG_NO_STDOUT_DEBUG */
    1586        1381 : }
    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        1381 : 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        1381 :         int ret = -1;
    1614        1381 :         struct wpa_peerkey *peerkey = NULL;
    1615             : 
    1616             : #ifdef CONFIG_IEEE80211R
    1617        1381 :         sm->ft_completed = 0;
    1618             : #endif /* CONFIG_IEEE80211R */
    1619             : 
    1620        1381 :         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        1381 :         tmp = os_malloc(len);
    1630        1381 :         if (tmp == NULL)
    1631           0 :                 return -1;
    1632        1381 :         os_memcpy(tmp, buf, len);
    1633             : 
    1634        1381 :         hdr = (struct ieee802_1x_hdr *) tmp;
    1635        1381 :         key = (struct wpa_eapol_key *) (hdr + 1);
    1636        1381 :         plen = be_to_host16(hdr->length);
    1637        1381 :         data_len = plen + sizeof(*hdr);
    1638        1381 :         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        1381 :         if (hdr->version < EAPOL_VERSION) {
    1643             :                 /* TODO: backwards compatibility */
    1644             :         }
    1645        1381 :         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        1381 :         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        1381 :         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        1381 :         wpa_eapol_key_dump(sm, key);
    1670             : 
    1671        1381 :         eapol_sm_notify_lower_layer_success(sm->eapol, 0);
    1672        1381 :         wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", tmp, len);
    1673        1381 :         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        1381 :         key_info = WPA_GET_BE16(key->key_info);
    1679        1381 :         ver = key_info & WPA_KEY_INFO_TYPE_MASK;
    1680        1381 :         if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
    1681             : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
    1682        1254 :             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        1381 :         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        1381 :         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
    1702             :                 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
    1703          40 :                 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        1341 :         if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
    1712          40 :                 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        1305 :         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        1305 :         } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
    1738             :                    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
    1739           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1740             :                         "WPA: GCMP is used, but EAPOL-Key "
    1741             :                         "descriptor version (%d) is not 2", ver);
    1742           0 :                 goto out;
    1743             :         }
    1744             : 
    1745             : #ifdef CONFIG_PEERKEY
    1746        1387 :         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
    1747          10 :                 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
    1748           4 :                         break;
    1749             :         }
    1750             : 
    1751        1381 :         if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
    1752           4 :                 if (!peerkey->initiator && peerkey->replay_counter_set &&
    1753           0 :                     os_memcmp(key->replay_counter, peerkey->replay_counter,
    1754             :                               WPA_REPLAY_COUNTER_LEN) <= 0) {
    1755           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1756             :                                 "RSN: EAPOL-Key Replay Counter did not "
    1757             :                                 "increase (STK) - dropping packet");
    1758           0 :                         goto out;
    1759           4 :                 } else if (peerkey->initiator) {
    1760             :                         u8 _tmp[WPA_REPLAY_COUNTER_LEN];
    1761           2 :                         os_memcpy(_tmp, key->replay_counter,
    1762             :                                   WPA_REPLAY_COUNTER_LEN);
    1763           2 :                         inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
    1764           2 :                         if (os_memcmp(_tmp, peerkey->replay_counter,
    1765             :                                       WPA_REPLAY_COUNTER_LEN) != 0) {
    1766           0 :                                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    1767             :                                         "RSN: EAPOL-Key Replay "
    1768             :                                         "Counter did not match (STK) - "
    1769             :                                         "dropping packet");
    1770           0 :                                 goto out;
    1771             :                         }
    1772             :                 }
    1773             :         }
    1774             : 
    1775        1381 :         if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
    1776           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1777             :                         "RSN: Ack bit in key_info from STK peer");
    1778           0 :                 goto out;
    1779             :         }
    1780             : #endif /* CONFIG_PEERKEY */
    1781             : 
    1782        1532 :         if (!peerkey && sm->rx_replay_counter_set &&
    1783         151 :             os_memcmp(key->replay_counter, sm->rx_replay_counter,
    1784             :                       WPA_REPLAY_COUNTER_LEN) <= 0) {
    1785           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1786             :                         "WPA: EAPOL-Key Replay Counter did not increase - "
    1787             :                         "dropping packet");
    1788           0 :                 goto out;
    1789             :         }
    1790             : 
    1791        1381 :         if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
    1792             : #ifdef CONFIG_PEERKEY
    1793           2 :             && (peerkey == NULL || !peerkey->initiator)
    1794             : #endif /* CONFIG_PEERKEY */
    1795             :                 ) {
    1796           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1797             :                         "WPA: No Ack bit in key_info");
    1798           0 :                 goto out;
    1799             :         }
    1800             : 
    1801        1381 :         if (key_info & WPA_KEY_INFO_REQUEST) {
    1802           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
    1803             :                         "WPA: EAPOL-Key with Request bit - dropped");
    1804           0 :                 goto out;
    1805             :         }
    1806             : 
    1807        2073 :         if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
    1808         692 :             wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
    1809           0 :                 goto out;
    1810             : 
    1811             : #ifdef CONFIG_PEERKEY
    1812        1384 :         if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
    1813           3 :             peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp, data_len))
    1814           0 :                 goto out;
    1815             : #endif /* CONFIG_PEERKEY */
    1816             : 
    1817        1381 :         extra_len = data_len - sizeof(*hdr) - sizeof(*key);
    1818             : 
    1819        1381 :         if (WPA_GET_BE16(key->key_data_length) > extra_len) {
    1820           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
    1821             :                         "frame - key_data overflow (%d > %lu)",
    1822           0 :                         WPA_GET_BE16(key->key_data_length),
    1823             :                         (unsigned long) extra_len);
    1824           0 :                 goto out;
    1825             :         }
    1826        1381 :         extra_len = WPA_GET_BE16(key->key_data_length);
    1827             : 
    1828        2710 :         if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
    1829        1329 :             (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
    1830         651 :                 if (wpa_supplicant_decrypt_key_data(sm, key, ver))
    1831           0 :                         goto out;
    1832         651 :                 extra_len = WPA_GET_BE16(key->key_data_length);
    1833             :         }
    1834             : 
    1835        1381 :         if (key_info & WPA_KEY_INFO_KEY_TYPE) {
    1836        1347 :                 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
    1837           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1838             :                                 "WPA: Ignored EAPOL-Key (Pairwise) with "
    1839             :                                 "non-zero key index");
    1840           0 :                         goto out;
    1841             :                 }
    1842        1347 :                 if (peerkey) {
    1843             :                         /* PeerKey 4-Way Handshake */
    1844           4 :                         peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver);
    1845        1343 :                 } else if (key_info & WPA_KEY_INFO_MIC) {
    1846             :                         /* 3/4 4-Way Handshake */
    1847         658 :                         wpa_supplicant_process_3_of_4(sm, key, ver);
    1848             :                 } else {
    1849             :                         /* 1/4 4-Way Handshake */
    1850         685 :                         wpa_supplicant_process_1_of_4(sm, src_addr, key,
    1851             :                                                       ver);
    1852             :                 }
    1853          34 :         } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
    1854             :                 /* PeerKey SMK Handshake */
    1855           8 :                 peerkey_rx_eapol_smk(sm, src_addr, key, extra_len, key_info,
    1856             :                                      ver);
    1857             :         } else {
    1858          26 :                 if (key_info & WPA_KEY_INFO_MIC) {
    1859             :                         /* 1/2 Group Key Handshake */
    1860          26 :                         wpa_supplicant_process_1_of_2(sm, src_addr, key,
    1861             :                                                       extra_len, ver);
    1862             :                 } else {
    1863           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
    1864             :                                 "WPA: EAPOL-Key (Group) without Mic bit - "
    1865             :                                 "dropped");
    1866             :                 }
    1867             :         }
    1868             : 
    1869        1381 :         ret = 1;
    1870             : 
    1871             : out:
    1872        1381 :         os_free(tmp);
    1873        1381 :         return ret;
    1874             : }
    1875             : 
    1876             : 
    1877             : #ifdef CONFIG_CTRL_IFACE
    1878          72 : static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
    1879             : {
    1880          72 :         switch (sm->key_mgmt) {
    1881             :         case WPA_KEY_MGMT_IEEE8021X:
    1882          40 :                 return ((sm->proto == WPA_PROTO_RSN ||
    1883           8 :                          sm->proto == WPA_PROTO_OSEN) ?
    1884          24 :                         RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
    1885             :                         WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
    1886             :         case WPA_KEY_MGMT_PSK:
    1887          16 :                 return (sm->proto == WPA_PROTO_RSN ?
    1888           8 :                         RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
    1889             :                         WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
    1890             : #ifdef CONFIG_IEEE80211R
    1891             :         case WPA_KEY_MGMT_FT_IEEE8021X:
    1892           8 :                 return RSN_AUTH_KEY_MGMT_FT_802_1X;
    1893             :         case WPA_KEY_MGMT_FT_PSK:
    1894           8 :                 return RSN_AUTH_KEY_MGMT_FT_PSK;
    1895             : #endif /* CONFIG_IEEE80211R */
    1896             : #ifdef CONFIG_IEEE80211W
    1897             :         case WPA_KEY_MGMT_IEEE8021X_SHA256:
    1898           8 :                 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
    1899             :         case WPA_KEY_MGMT_PSK_SHA256:
    1900          16 :                 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
    1901             : #endif /* CONFIG_IEEE80211W */
    1902             :         case WPA_KEY_MGMT_CCKM:
    1903           0 :                 return (sm->proto == WPA_PROTO_RSN ?
    1904             :                         RSN_AUTH_KEY_MGMT_CCKM:
    1905             :                         WPA_AUTH_KEY_MGMT_CCKM);
    1906             :         case WPA_KEY_MGMT_WPA_NONE:
    1907           0 :                 return WPA_AUTH_KEY_MGMT_NONE;
    1908             :         default:
    1909           8 :                 return 0;
    1910             :         }
    1911             : }
    1912             : 
    1913             : 
    1914             : #define RSN_SUITE "%02x-%02x-%02x-%d"
    1915             : #define RSN_SUITE_ARG(s) \
    1916             : ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
    1917             : 
    1918             : /**
    1919             :  * wpa_sm_get_mib - Dump text list of MIB entries
    1920             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    1921             :  * @buf: Buffer for the list
    1922             :  * @buflen: Length of the buffer
    1923             :  * Returns: Number of bytes written to buffer
    1924             :  *
    1925             :  * This function is used fetch dot11 MIB variables.
    1926             :  */
    1927           9 : int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
    1928             : {
    1929             :         char pmkid_txt[PMKID_LEN * 2 + 1];
    1930             :         int rsna, ret;
    1931             :         size_t len;
    1932             : 
    1933           9 :         if (sm->cur_pmksa) {
    1934           2 :                 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
    1935           2 :                                  sm->cur_pmksa->pmkid, PMKID_LEN);
    1936             :         } else
    1937           7 :                 pmkid_txt[0] = '\0';
    1938             : 
    1939          14 :         if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
    1940          13 :              wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
    1941           8 :             sm->proto == WPA_PROTO_RSN)
    1942           6 :                 rsna = 1;
    1943             :         else
    1944           3 :                 rsna = 0;
    1945             : 
    1946          18 :         ret = os_snprintf(buf, buflen,
    1947             :                           "dot11RSNAOptionImplemented=TRUE\n"
    1948             :                           "dot11RSNAPreauthenticationImplemented=TRUE\n"
    1949             :                           "dot11RSNAEnabled=%s\n"
    1950             :                           "dot11RSNAPreauthenticationEnabled=%s\n"
    1951             :                           "dot11RSNAConfigVersion=%d\n"
    1952             :                           "dot11RSNAConfigPairwiseKeysSupported=5\n"
    1953             :                           "dot11RSNAConfigGroupCipherSize=%d\n"
    1954             :                           "dot11RSNAConfigPMKLifetime=%d\n"
    1955             :                           "dot11RSNAConfigPMKReauthThreshold=%d\n"
    1956             :                           "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
    1957             :                           "dot11RSNAConfigSATimeout=%d\n",
    1958             :                           rsna ? "TRUE" : "FALSE",
    1959             :                           rsna ? "TRUE" : "FALSE",
    1960             :                           RSN_VERSION,
    1961           9 :                           wpa_cipher_key_len(sm->group_cipher) * 8,
    1962             :                           sm->dot11RSNAConfigPMKLifetime,
    1963             :                           sm->dot11RSNAConfigPMKReauthThreshold,
    1964             :                           sm->dot11RSNAConfigSATimeout);
    1965           9 :         if (ret < 0 || (size_t) ret >= buflen)
    1966           0 :                 return 0;
    1967           9 :         len = ret;
    1968             : 
    1969         225 :         ret = os_snprintf(
    1970             :                 buf + len, buflen - len,
    1971             :                 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
    1972             :                 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
    1973             :                 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
    1974             :                 "dot11RSNAPMKIDUsed=%s\n"
    1975             :                 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
    1976             :                 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
    1977             :                 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
    1978             :                 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
    1979             :                 "dot11RSNA4WayHandshakeFailures=%u\n",
    1980          36 :                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
    1981          36 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    1982             :                                                   sm->pairwise_cipher)),
    1983          36 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    1984             :                                                   sm->group_cipher)),
    1985             :                 pmkid_txt,
    1986          36 :                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
    1987          36 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    1988             :                                                   sm->pairwise_cipher)),
    1989          36 :                 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
    1990             :                                                   sm->group_cipher)),
    1991             :                 sm->dot11RSNA4WayHandshakeFailures);
    1992           9 :         if (ret >= 0 && (size_t) ret < buflen)
    1993           9 :                 len += ret;
    1994             : 
    1995           9 :         return (int) len;
    1996             : }
    1997             : #endif /* CONFIG_CTRL_IFACE */
    1998             : 
    1999             : 
    2000         277 : static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
    2001             :                                  void *ctx, enum pmksa_free_reason reason)
    2002             : {
    2003         277 :         struct wpa_sm *sm = ctx;
    2004         277 :         int deauth = 0;
    2005             : 
    2006         277 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
    2007             :                 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
    2008             : 
    2009         277 :         if (sm->cur_pmksa == entry) {
    2010          28 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2011             :                         "RSN: %s current PMKSA entry",
    2012             :                         reason == PMKSA_REPLACE ? "replaced" : "removed");
    2013          28 :                 pmksa_cache_clear_current(sm);
    2014             : 
    2015             :                 /*
    2016             :                  * If an entry is simply being replaced, there's no need to
    2017             :                  * deauthenticate because it will be immediately re-added.
    2018             :                  * This happens when EAP authentication is completed again
    2019             :                  * (reauth or failed PMKSA caching attempt).
    2020             :                  */
    2021          28 :                 if (reason != PMKSA_REPLACE)
    2022          27 :                         deauth = 1;
    2023             :         }
    2024             : 
    2025         278 :         if (reason == PMKSA_EXPIRE &&
    2026           2 :             (sm->pmk_len == entry->pmk_len &&
    2027           1 :              os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
    2028           1 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2029             :                         "RSN: deauthenticating due to expired PMK");
    2030           1 :                 pmksa_cache_clear_current(sm);
    2031           1 :                 deauth = 1;
    2032             :         }
    2033             : 
    2034         277 :         if (deauth) {
    2035          28 :                 os_memset(sm->pmk, 0, sizeof(sm->pmk));
    2036          28 :                 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
    2037             :         }
    2038         277 : }
    2039             : 
    2040             : 
    2041             : /**
    2042             :  * wpa_sm_init - Initialize WPA state machine
    2043             :  * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
    2044             :  * Returns: Pointer to the allocated WPA state machine data
    2045             :  *
    2046             :  * This function is used to allocate a new WPA state machine and the returned
    2047             :  * value is passed to all WPA state machine calls.
    2048             :  */
    2049          84 : struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
    2050             : {
    2051             :         struct wpa_sm *sm;
    2052             : 
    2053          84 :         sm = os_zalloc(sizeof(*sm));
    2054          84 :         if (sm == NULL)
    2055           0 :                 return NULL;
    2056          84 :         dl_list_init(&sm->pmksa_candidates);
    2057          84 :         sm->renew_snonce = 1;
    2058          84 :         sm->ctx = ctx;
    2059             : 
    2060          84 :         sm->dot11RSNAConfigPMKLifetime = 43200;
    2061          84 :         sm->dot11RSNAConfigPMKReauthThreshold = 70;
    2062          84 :         sm->dot11RSNAConfigSATimeout = 60;
    2063             : 
    2064          84 :         sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
    2065          84 :         if (sm->pmksa == NULL) {
    2066           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
    2067             :                         "RSN: PMKSA cache initialization failed");
    2068           0 :                 os_free(sm);
    2069           0 :                 return NULL;
    2070             :         }
    2071             : 
    2072          84 :         return sm;
    2073             : }
    2074             : 
    2075             : 
    2076             : /**
    2077             :  * wpa_sm_deinit - Deinitialize WPA state machine
    2078             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2079             :  */
    2080          93 : void wpa_sm_deinit(struct wpa_sm *sm)
    2081             : {
    2082          93 :         if (sm == NULL)
    2083         102 :                 return;
    2084          84 :         pmksa_cache_deinit(sm->pmksa);
    2085          84 :         eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
    2086          84 :         eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
    2087          84 :         os_free(sm->assoc_wpa_ie);
    2088          84 :         os_free(sm->ap_wpa_ie);
    2089          84 :         os_free(sm->ap_rsn_ie);
    2090          84 :         os_free(sm->ctx);
    2091          84 :         peerkey_deinit(sm);
    2092             : #ifdef CONFIG_IEEE80211R
    2093          84 :         os_free(sm->assoc_resp_ies);
    2094             : #endif /* CONFIG_IEEE80211R */
    2095          84 :         os_free(sm);
    2096             : }
    2097             : 
    2098             : 
    2099             : /**
    2100             :  * wpa_sm_notify_assoc - Notify WPA state machine about association
    2101             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2102             :  * @bssid: The BSSID of the new association
    2103             :  *
    2104             :  * This function is called to let WPA state machine know that the connection
    2105             :  * was established.
    2106             :  */
    2107        1308 : void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
    2108             : {
    2109        1308 :         int clear_ptk = 1;
    2110             : 
    2111        1308 :         if (sm == NULL)
    2112        1308 :                 return;
    2113             : 
    2114        1308 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2115             :                 "WPA: Association event - clear replay counter");
    2116        1308 :         os_memcpy(sm->bssid, bssid, ETH_ALEN);
    2117        1308 :         os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
    2118        1308 :         sm->rx_replay_counter_set = 0;
    2119        1308 :         sm->renew_snonce = 1;
    2120        1308 :         if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
    2121           0 :                 rsn_preauth_deinit(sm);
    2122             : 
    2123             : #ifdef CONFIG_IEEE80211R
    2124        1308 :         if (wpa_ft_is_completed(sm)) {
    2125             :                 /*
    2126             :                  * Clear portValid to kick EAPOL state machine to re-enter
    2127             :                  * AUTHENTICATED state to get the EAPOL port Authorized.
    2128             :                  */
    2129         221 :                 eapol_sm_notify_portValid(sm->eapol, FALSE);
    2130         221 :                 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
    2131             : 
    2132             :                 /* Prepare for the next transition */
    2133         221 :                 wpa_ft_prepare_auth_request(sm, NULL);
    2134             : 
    2135         221 :                 clear_ptk = 0;
    2136             :         }
    2137             : #endif /* CONFIG_IEEE80211R */
    2138             : 
    2139        1308 :         if (clear_ptk) {
    2140             :                 /*
    2141             :                  * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
    2142             :                  * this is not part of a Fast BSS Transition.
    2143             :                  */
    2144        1087 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
    2145        1087 :                 sm->ptk_set = 0;
    2146        1087 :                 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
    2147        1087 :                 sm->tptk_set = 0;
    2148        1087 :                 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    2149             :         }
    2150             : 
    2151             : #ifdef CONFIG_TDLS
    2152        1308 :         wpa_tdls_assoc(sm);
    2153             : #endif /* CONFIG_TDLS */
    2154             : 
    2155             : #ifdef CONFIG_P2P
    2156        1308 :         os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
    2157             : #endif /* CONFIG_P2P */
    2158             : }
    2159             : 
    2160             : 
    2161             : /**
    2162             :  * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
    2163             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2164             :  *
    2165             :  * This function is called to let WPA state machine know that the connection
    2166             :  * was lost. This will abort any existing pre-authentication session.
    2167             :  */
    2168        1146 : void wpa_sm_notify_disassoc(struct wpa_sm *sm)
    2169             : {
    2170        1146 :         peerkey_deinit(sm);
    2171        1146 :         rsn_preauth_deinit(sm);
    2172        1146 :         pmksa_cache_clear_current(sm);
    2173        1146 :         if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
    2174           6 :                 sm->dot11RSNA4WayHandshakeFailures++;
    2175             : #ifdef CONFIG_TDLS
    2176        1146 :         wpa_tdls_disassoc(sm);
    2177             : #endif /* CONFIG_TDLS */
    2178        1146 : }
    2179             : 
    2180             : 
    2181             : /**
    2182             :  * wpa_sm_set_pmk - Set PMK
    2183             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2184             :  * @pmk: The new PMK
    2185             :  * @pmk_len: The length of the new PMK in bytes
    2186             :  *
    2187             :  * Configure the PMK for WPA state machine.
    2188             :  */
    2189         543 : void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len)
    2190             : {
    2191         543 :         if (sm == NULL)
    2192         543 :                 return;
    2193             : 
    2194         543 :         sm->pmk_len = pmk_len;
    2195         543 :         os_memcpy(sm->pmk, pmk, pmk_len);
    2196             : 
    2197             : #ifdef CONFIG_IEEE80211R
    2198             :         /* Set XXKey to be PSK for FT key derivation */
    2199         543 :         sm->xxkey_len = pmk_len;
    2200         543 :         os_memcpy(sm->xxkey, pmk, pmk_len);
    2201             : #endif /* CONFIG_IEEE80211R */
    2202             : }
    2203             : 
    2204             : 
    2205             : /**
    2206             :  * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
    2207             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2208             :  *
    2209             :  * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
    2210             :  * will be cleared.
    2211             :  */
    2212         321 : void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
    2213             : {
    2214         321 :         if (sm == NULL)
    2215         321 :                 return;
    2216             : 
    2217         321 :         if (sm->cur_pmksa) {
    2218          25 :                 sm->pmk_len = sm->cur_pmksa->pmk_len;
    2219          25 :                 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
    2220             :         } else {
    2221         296 :                 sm->pmk_len = PMK_LEN;
    2222         296 :                 os_memset(sm->pmk, 0, PMK_LEN);
    2223             :         }
    2224             : }
    2225             : 
    2226             : 
    2227             : /**
    2228             :  * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
    2229             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2230             :  * @fast_reauth: Whether fast reauthentication (EAP) is allowed
    2231             :  */
    2232          72 : void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
    2233             : {
    2234          72 :         if (sm)
    2235          72 :                 sm->fast_reauth = fast_reauth;
    2236          72 : }
    2237             : 
    2238             : 
    2239             : /**
    2240             :  * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
    2241             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2242             :  * @scard_ctx: Context pointer for smartcard related callback functions
    2243             :  */
    2244          81 : void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
    2245             : {
    2246          81 :         if (sm == NULL)
    2247          90 :                 return;
    2248          72 :         sm->scard_ctx = scard_ctx;
    2249          72 :         if (sm->preauth_eapol)
    2250           0 :                 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
    2251             : }
    2252             : 
    2253             : 
    2254             : /**
    2255             :  * wpa_sm_set_config - Notification of current configration change
    2256             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2257             :  * @config: Pointer to current network configuration
    2258             :  *
    2259             :  * Notify WPA state machine that configuration has changed. config will be
    2260             :  * stored as a backpointer to network configuration. This can be %NULL to clear
    2261             :  * the stored pointed.
    2262             :  */
    2263        2688 : void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
    2264             : {
    2265        2688 :         if (!sm)
    2266        2688 :                 return;
    2267             : 
    2268        2688 :         if (config) {
    2269        1241 :                 sm->network_ctx = config->network_ctx;
    2270        1241 :                 sm->peerkey_enabled = config->peerkey_enabled;
    2271        1241 :                 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
    2272        1241 :                 sm->proactive_key_caching = config->proactive_key_caching;
    2273        1241 :                 sm->eap_workaround = config->eap_workaround;
    2274        1241 :                 sm->eap_conf_ctx = config->eap_conf_ctx;
    2275        1241 :                 if (config->ssid) {
    2276        1154 :                         os_memcpy(sm->ssid, config->ssid, config->ssid_len);
    2277        1154 :                         sm->ssid_len = config->ssid_len;
    2278             :                 } else
    2279          87 :                         sm->ssid_len = 0;
    2280        1241 :                 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
    2281        1241 :                 sm->p2p = config->p2p;
    2282             :         } else {
    2283        1447 :                 sm->network_ctx = NULL;
    2284        1447 :                 sm->peerkey_enabled = 0;
    2285        1447 :                 sm->allowed_pairwise_cipher = 0;
    2286        1447 :                 sm->proactive_key_caching = 0;
    2287        1447 :                 sm->eap_workaround = 0;
    2288        1447 :                 sm->eap_conf_ctx = NULL;
    2289        1447 :                 sm->ssid_len = 0;
    2290        1447 :                 sm->wpa_ptk_rekey = 0;
    2291        1447 :                 sm->p2p = 0;
    2292             :         }
    2293             : }
    2294             : 
    2295             : 
    2296             : /**
    2297             :  * wpa_sm_set_own_addr - Set own MAC address
    2298             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2299             :  * @addr: Own MAC address
    2300             :  */
    2301          84 : void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
    2302             : {
    2303          84 :         if (sm)
    2304          84 :                 os_memcpy(sm->own_addr, addr, ETH_ALEN);
    2305          84 : }
    2306             : 
    2307             : 
    2308             : /**
    2309             :  * wpa_sm_set_ifname - Set network interface name
    2310             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2311             :  * @ifname: Interface name
    2312             :  * @bridge_ifname: Optional bridge interface name (for pre-auth)
    2313             :  */
    2314          72 : void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
    2315             :                        const char *bridge_ifname)
    2316             : {
    2317          72 :         if (sm) {
    2318          72 :                 sm->ifname = ifname;
    2319          72 :                 sm->bridge_ifname = bridge_ifname;
    2320             :         }
    2321          72 : }
    2322             : 
    2323             : 
    2324             : /**
    2325             :  * wpa_sm_set_eapol - Set EAPOL state machine pointer
    2326             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2327             :  * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
    2328             :  */
    2329         153 : void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
    2330             : {
    2331         153 :         if (sm)
    2332         144 :                 sm->eapol = eapol;
    2333         153 : }
    2334             : 
    2335             : 
    2336             : /**
    2337             :  * wpa_sm_set_param - Set WPA state machine parameters
    2338             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2339             :  * @param: Parameter field
    2340             :  * @value: Parameter value
    2341             :  * Returns: 0 on success, -1 on failure
    2342             :  */
    2343       13920 : int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
    2344             :                      unsigned int value)
    2345             : {
    2346       13920 :         int ret = 0;
    2347             : 
    2348       13920 :         if (sm == NULL)
    2349           0 :                 return -1;
    2350             : 
    2351       13920 :         switch (param) {
    2352             :         case RSNA_PMK_LIFETIME:
    2353        1999 :                 if (value > 0)
    2354        1998 :                         sm->dot11RSNAConfigPMKLifetime = value;
    2355             :                 else
    2356           1 :                         ret = -1;
    2357        1999 :                 break;
    2358             :         case RSNA_PMK_REAUTH_THRESHOLD:
    2359        1998 :                 if (value > 0 && value <= 100)
    2360        1997 :                         sm->dot11RSNAConfigPMKReauthThreshold = value;
    2361             :                 else
    2362           1 :                         ret = -1;
    2363        1998 :                 break;
    2364             :         case RSNA_SA_TIMEOUT:
    2365        1998 :                 if (value > 0)
    2366        1997 :                         sm->dot11RSNAConfigSATimeout = value;
    2367             :                 else
    2368           1 :                         ret = -1;
    2369        1998 :                 break;
    2370             :         case WPA_PARAM_PROTO:
    2371         832 :                 sm->proto = value;
    2372         832 :                 break;
    2373             :         case WPA_PARAM_PAIRWISE:
    2374        1257 :                 sm->pairwise_cipher = value;
    2375        1257 :                 break;
    2376             :         case WPA_PARAM_GROUP:
    2377        1257 :                 sm->group_cipher = value;
    2378        1257 :                 break;
    2379             :         case WPA_PARAM_KEY_MGMT:
    2380        1257 :                 sm->key_mgmt = value;
    2381        1257 :                 break;
    2382             : #ifdef CONFIG_IEEE80211W
    2383             :         case WPA_PARAM_MGMT_GROUP:
    2384        1245 :                 sm->mgmt_group_cipher = value;
    2385        1245 :                 break;
    2386             : #endif /* CONFIG_IEEE80211W */
    2387             :         case WPA_PARAM_RSN_ENABLED:
    2388        1257 :                 sm->rsn_enabled = value;
    2389        1257 :                 break;
    2390             :         case WPA_PARAM_MFP:
    2391         820 :                 sm->mfp = value;
    2392         820 :                 break;
    2393             :         default:
    2394           0 :                 break;
    2395             :         }
    2396             : 
    2397       13920 :         return ret;
    2398             : }
    2399             : 
    2400             : 
    2401             : /**
    2402             :  * wpa_sm_get_status - Get WPA state machine
    2403             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2404             :  * @buf: Buffer for status information
    2405             :  * @buflen: Maximum buffer length
    2406             :  * @verbose: Whether to include verbose status information
    2407             :  * Returns: Number of bytes written to buf.
    2408             :  *
    2409             :  * Query WPA state machine for status information. This function fills in
    2410             :  * a text area with current status information. If the buffer (buf) is not
    2411             :  * large enough, status information will be truncated to fit the buffer.
    2412             :  */
    2413         669 : int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
    2414             :                       int verbose)
    2415             : {
    2416         669 :         char *pos = buf, *end = buf + buflen;
    2417             :         int ret;
    2418             : 
    2419        2676 :         ret = os_snprintf(pos, end - pos,
    2420             :                           "pairwise_cipher=%s\n"
    2421             :                           "group_cipher=%s\n"
    2422             :                           "key_mgmt=%s\n",
    2423         669 :                           wpa_cipher_txt(sm->pairwise_cipher),
    2424         669 :                           wpa_cipher_txt(sm->group_cipher),
    2425        1338 :                           wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
    2426         669 :         if (ret < 0 || ret >= end - pos)
    2427           0 :                 return pos - buf;
    2428         669 :         pos += ret;
    2429             : 
    2430         669 :         if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
    2431             :                 struct wpa_ie_data rsn;
    2432         395 :                 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
    2433         395 :                     >= 0 &&
    2434         395 :                     rsn.capabilities & (WPA_CAPABILITY_MFPR |
    2435             :                                         WPA_CAPABILITY_MFPC)) {
    2436          28 :                         ret = os_snprintf(pos, end - pos, "pmf=%d\n",
    2437          28 :                                           (rsn.capabilities &
    2438             :                                            WPA_CAPABILITY_MFPR) ? 2 : 1);
    2439          28 :                         if (ret < 0 || ret >= end - pos)
    2440           0 :                                 return pos - buf;
    2441          28 :                         pos += ret;
    2442             :                 }
    2443             :         }
    2444             : 
    2445         669 :         return pos - buf;
    2446             : }
    2447             : 
    2448             : 
    2449          49 : int wpa_sm_pmf_enabled(struct wpa_sm *sm)
    2450             : {
    2451             :         struct wpa_ie_data rsn;
    2452             : 
    2453          49 :         if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
    2454          42 :                 return 0;
    2455             : 
    2456          14 :         if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
    2457           7 :             rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
    2458           7 :                 return 1;
    2459             : 
    2460           0 :         return 0;
    2461             : }
    2462             : 
    2463             : 
    2464             : /**
    2465             :  * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
    2466             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2467             :  * @wpa_ie: Pointer to buffer for WPA/RSN IE
    2468             :  * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
    2469             :  * Returns: 0 on success, -1 on failure
    2470             :  */
    2471         832 : int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
    2472             :                                     size_t *wpa_ie_len)
    2473             : {
    2474             :         int res;
    2475             : 
    2476         832 :         if (sm == NULL)
    2477           0 :                 return -1;
    2478             : 
    2479         832 :         res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
    2480         832 :         if (res < 0)
    2481           0 :                 return -1;
    2482         832 :         *wpa_ie_len = res;
    2483             : 
    2484         832 :         wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
    2485             :                     wpa_ie, *wpa_ie_len);
    2486             : 
    2487         832 :         if (sm->assoc_wpa_ie == NULL) {
    2488             :                 /*
    2489             :                  * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
    2490             :                  * the correct version of the IE even if PMKSA caching is
    2491             :                  * aborted (which would remove PMKID from IE generation).
    2492             :                  */
    2493         237 :                 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
    2494         237 :                 if (sm->assoc_wpa_ie == NULL)
    2495           0 :                         return -1;
    2496             : 
    2497         237 :                 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
    2498         237 :                 sm->assoc_wpa_ie_len = *wpa_ie_len;
    2499             :         }
    2500             : 
    2501         832 :         return 0;
    2502             : }
    2503             : 
    2504             : 
    2505             : /**
    2506             :  * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
    2507             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2508             :  * @ie: Pointer to IE data (starting from id)
    2509             :  * @len: IE length
    2510             :  * Returns: 0 on success, -1 on failure
    2511             :  *
    2512             :  * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
    2513             :  * Request frame. The IE will be used to override the default value generated
    2514             :  * with wpa_sm_set_assoc_wpa_ie_default().
    2515             :  */
    2516        1715 : int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2517             : {
    2518        1715 :         if (sm == NULL)
    2519           0 :                 return -1;
    2520             : 
    2521        1715 :         os_free(sm->assoc_wpa_ie);
    2522        1715 :         if (ie == NULL || len == 0) {
    2523         843 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2524             :                         "WPA: clearing own WPA/RSN IE");
    2525         843 :                 sm->assoc_wpa_ie = NULL;
    2526         843 :                 sm->assoc_wpa_ie_len = 0;
    2527             :         } else {
    2528         872 :                 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
    2529         872 :                 sm->assoc_wpa_ie = os_malloc(len);
    2530         872 :                 if (sm->assoc_wpa_ie == NULL)
    2531           0 :                         return -1;
    2532             : 
    2533         872 :                 os_memcpy(sm->assoc_wpa_ie, ie, len);
    2534         872 :                 sm->assoc_wpa_ie_len = len;
    2535             :         }
    2536             : 
    2537        1715 :         return 0;
    2538             : }
    2539             : 
    2540             : 
    2541             : /**
    2542             :  * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
    2543             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2544             :  * @ie: Pointer to IE data (starting from id)
    2545             :  * @len: IE length
    2546             :  * Returns: 0 on success, -1 on failure
    2547             :  *
    2548             :  * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
    2549             :  * frame.
    2550             :  */
    2551        1249 : int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2552             : {
    2553        1249 :         if (sm == NULL)
    2554           0 :                 return -1;
    2555             : 
    2556        1249 :         os_free(sm->ap_wpa_ie);
    2557        1249 :         if (ie == NULL || len == 0) {
    2558        1214 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2559             :                         "WPA: clearing AP WPA IE");
    2560        1214 :                 sm->ap_wpa_ie = NULL;
    2561        1214 :                 sm->ap_wpa_ie_len = 0;
    2562             :         } else {
    2563          35 :                 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
    2564          35 :                 sm->ap_wpa_ie = os_malloc(len);
    2565          35 :                 if (sm->ap_wpa_ie == NULL)
    2566           0 :                         return -1;
    2567             : 
    2568          35 :                 os_memcpy(sm->ap_wpa_ie, ie, len);
    2569          35 :                 sm->ap_wpa_ie_len = len;
    2570             :         }
    2571             : 
    2572        1249 :         return 0;
    2573             : }
    2574             : 
    2575             : 
    2576             : /**
    2577             :  * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
    2578             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2579             :  * @ie: Pointer to IE data (starting from id)
    2580             :  * @len: IE length
    2581             :  * Returns: 0 on success, -1 on failure
    2582             :  *
    2583             :  * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
    2584             :  * frame.
    2585             :  */
    2586        1259 : int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
    2587             : {
    2588        1259 :         if (sm == NULL)
    2589           0 :                 return -1;
    2590             : 
    2591        1259 :         os_free(sm->ap_rsn_ie);
    2592        1259 :         if (ie == NULL || len == 0) {
    2593         452 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2594             :                         "WPA: clearing AP RSN IE");
    2595         452 :                 sm->ap_rsn_ie = NULL;
    2596         452 :                 sm->ap_rsn_ie_len = 0;
    2597             :         } else {
    2598         807 :                 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
    2599         807 :                 sm->ap_rsn_ie = os_malloc(len);
    2600         807 :                 if (sm->ap_rsn_ie == NULL)
    2601           0 :                         return -1;
    2602             : 
    2603         807 :                 os_memcpy(sm->ap_rsn_ie, ie, len);
    2604         807 :                 sm->ap_rsn_ie_len = len;
    2605             :         }
    2606             : 
    2607        1259 :         return 0;
    2608             : }
    2609             : 
    2610             : 
    2611             : /**
    2612             :  * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
    2613             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
    2614             :  * @data: Pointer to data area for parsing results
    2615             :  * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
    2616             :  *
    2617             :  * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
    2618             :  * parsed data into data.
    2619             :  */
    2620          13 : int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
    2621             : {
    2622          13 :         if (sm == NULL)
    2623           0 :                 return -1;
    2624             : 
    2625          13 :         if (sm->assoc_wpa_ie == NULL) {
    2626          10 :                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
    2627             :                         "WPA: No WPA/RSN IE available from association info");
    2628          10 :                 return -1;
    2629             :         }
    2630           3 :         if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
    2631           0 :                 return -2;
    2632           3 :         return 0;
    2633             : }
    2634             : 
    2635             : 
    2636          31 : int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
    2637             : {
    2638          31 :         return pmksa_cache_list(sm->pmksa, buf, len);
    2639             : }
    2640             : 
    2641             : 
    2642             : #ifdef CONFIG_TESTING_OPTIONS
    2643           1 : void wpa_sm_drop_sa(struct wpa_sm *sm)
    2644             : {
    2645           1 :         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
    2646           1 :         sm->ptk_set = 0;
    2647           1 :         sm->tptk_set = 0;
    2648           1 :         os_memset(sm->pmk, 0, sizeof(sm->pmk));
    2649           1 :         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
    2650           1 :         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
    2651           1 : }
    2652             : #endif /* CONFIG_TESTING_OPTIONS */
    2653             : 
    2654             : 
    2655         113 : int wpa_sm_has_ptk(struct wpa_sm *sm)
    2656             : {
    2657         113 :         if (sm == NULL)
    2658           0 :                 return 0;
    2659         113 :         return sm->ptk_set;
    2660             : }
    2661             : 
    2662             : 
    2663           0 : void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
    2664             : {
    2665           0 :         os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
    2666           0 : }
    2667             : 
    2668             : 
    2669        3877 : void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
    2670             : {
    2671        3877 :         pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
    2672        3877 : }
    2673             : 
    2674             : 
    2675             : #ifdef CONFIG_WNM
    2676           2 : int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
    2677             : {
    2678             :         u16 keyinfo;
    2679             :         u8 keylen;  /* plaintext key len */
    2680             :         u8 *key_rsc;
    2681             : 
    2682           2 :         if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
    2683             :                 struct wpa_gtk_data gd;
    2684             : 
    2685           1 :                 os_memset(&gd, 0, sizeof(gd));
    2686           1 :                 keylen = wpa_cipher_key_len(sm->group_cipher);
    2687           1 :                 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
    2688           1 :                 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
    2689           1 :                 if (gd.alg == WPA_ALG_NONE) {
    2690           0 :                         wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
    2691           0 :                         return -1;
    2692             :                 }
    2693             : 
    2694           1 :                 key_rsc = buf + 5;
    2695           1 :                 keyinfo = WPA_GET_LE16(buf + 2);
    2696           1 :                 gd.gtk_len = keylen;
    2697           1 :                 if (gd.gtk_len != buf[4]) {
    2698           0 :                         wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
    2699           0 :                                    gd.gtk_len, buf[4]);
    2700           0 :                         return -1;
    2701             :                 }
    2702           1 :                 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
    2703           1 :                 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
    2704           1 :                          sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
    2705             : 
    2706           1 :                 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
    2707             : 
    2708           1 :                 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
    2709           1 :                                 gd.gtk, gd.gtk_len);
    2710           1 :                 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
    2711           0 :                         os_memset(&gd, 0, sizeof(gd));
    2712           0 :                         wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
    2713             :                                    "WNM mode");
    2714           0 :                         return -1;
    2715             :                 }
    2716           1 :                 os_memset(&gd, 0, sizeof(gd));
    2717             : #ifdef CONFIG_IEEE80211W
    2718           1 :         } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
    2719             :                 struct wpa_igtk_kde igd;
    2720             :                 u16 keyidx;
    2721             : 
    2722           1 :                 os_memset(&igd, 0, sizeof(igd));
    2723           1 :                 keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
    2724           1 :                 os_memcpy(igd.keyid, buf + 2, 2);
    2725           1 :                 os_memcpy(igd.pn, buf + 4, 6);
    2726             : 
    2727           1 :                 keyidx = WPA_GET_LE16(igd.keyid);
    2728           1 :                 os_memcpy(igd.igtk, buf + 10, keylen);
    2729             : 
    2730           1 :                 wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
    2731             :                                 igd.igtk, keylen);
    2732           1 :                 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
    2733             :                                    broadcast_ether_addr,
    2734             :                                    keyidx, 0, igd.pn, sizeof(igd.pn),
    2735             :                                    igd.igtk, keylen) < 0) {
    2736           0 :                         wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
    2737             :                                    "WNM mode");
    2738           0 :                         os_memset(&igd, 0, sizeof(igd));
    2739           0 :                         return -1;
    2740             :                 }
    2741           1 :                 os_memset(&igd, 0, sizeof(igd));
    2742             : #endif /* CONFIG_IEEE80211W */
    2743             :         } else {
    2744           0 :                 wpa_printf(MSG_DEBUG, "Unknown element id");
    2745           0 :                 return -1;
    2746             :         }
    2747             : 
    2748           2 :         return 0;
    2749             : }
    2750             : #endif /* CONFIG_WNM */
    2751             : 
    2752             : 
    2753             : #ifdef CONFIG_PEERKEY
    2754          18 : int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
    2755             :                             const u8 *buf, size_t len)
    2756             : {
    2757             :         struct wpa_peerkey *peerkey;
    2758             : 
    2759          24 :         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
    2760          10 :                 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
    2761           4 :                         break;
    2762             :         }
    2763             : 
    2764          18 :         if (!peerkey)
    2765          14 :                 return 0;
    2766             : 
    2767           4 :         wpa_sm_rx_eapol(sm, src_addr, buf, len);
    2768             : 
    2769           4 :         return 1;
    2770             : }
    2771             : #endif /* CONFIG_PEERKEY */
    2772             : 
    2773             : 
    2774             : #ifdef CONFIG_P2P
    2775             : 
    2776         127 : int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
    2777             : {
    2778         127 :         if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
    2779          43 :                 return -1;
    2780          84 :         os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
    2781          84 :         return 0;
    2782             : }
    2783             : 
    2784             : #endif /* CONFIG_P2P */

Generated by: LCOV version 1.10