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 1475438200 Lines: 1156 1375 84.1 %
Date: 2016-10-02 Functions: 65 68 95.6 %

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

Generated by: LCOV version 1.10