LCOV - code coverage report
Current view: top level - wpa_supplicant - wpas_glue.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 435 509 85.5 %
Date: 2016-10-02 Functions: 47 47 100.0 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant - Glue code to setup EAPOL and RSN modules
       3             :  * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "eapol_supp/eapol_supp_sm.h"
      13             : #include "rsn_supp/wpa.h"
      14             : #include "eloop.h"
      15             : #include "config.h"
      16             : #include "l2_packet/l2_packet.h"
      17             : #include "common/wpa_common.h"
      18             : #include "wpa_supplicant_i.h"
      19             : #include "driver_i.h"
      20             : #include "rsn_supp/pmksa_cache.h"
      21             : #include "sme.h"
      22             : #include "common/ieee802_11_defs.h"
      23             : #include "common/wpa_ctrl.h"
      24             : #include "wpas_glue.h"
      25             : #include "wps_supplicant.h"
      26             : #include "bss.h"
      27             : #include "scan.h"
      28             : #include "notify.h"
      29             : #include "wpas_kay.h"
      30             : 
      31             : 
      32             : #ifndef CONFIG_NO_CONFIG_BLOBS
      33             : #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
      34          43 : static void wpa_supplicant_set_config_blob(void *ctx,
      35             :                                            struct wpa_config_blob *blob)
      36             : {
      37          43 :         struct wpa_supplicant *wpa_s = ctx;
      38          43 :         wpa_config_set_blob(wpa_s->conf, blob);
      39          43 :         if (wpa_s->conf->update_config) {
      40           0 :                 int ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
      41           0 :                 if (ret) {
      42           0 :                         wpa_printf(MSG_DEBUG, "Failed to update config after "
      43             :                                    "blob set");
      44             :                 }
      45             :         }
      46          43 : }
      47             : 
      48             : 
      49             : static const struct wpa_config_blob *
      50         165 : wpa_supplicant_get_config_blob(void *ctx, const char *name)
      51             : {
      52         165 :         struct wpa_supplicant *wpa_s = ctx;
      53         165 :         return wpa_config_get_blob(wpa_s->conf, name);
      54             : }
      55             : #endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
      56             : #endif /* CONFIG_NO_CONFIG_BLOBS */
      57             : 
      58             : 
      59             : #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
      60       16542 : static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
      61             :                             const void *data, u16 data_len,
      62             :                             size_t *msg_len, void **data_pos)
      63             : {
      64             :         struct ieee802_1x_hdr *hdr;
      65             : 
      66       16542 :         *msg_len = sizeof(*hdr) + data_len;
      67       16542 :         hdr = os_malloc(*msg_len);
      68       16542 :         if (hdr == NULL)
      69           0 :                 return NULL;
      70             : 
      71       16542 :         hdr->version = wpa_s->conf->eapol_version;
      72       16542 :         hdr->type = type;
      73       16542 :         hdr->length = host_to_be16(data_len);
      74             : 
      75       16542 :         if (data)
      76       12123 :                 os_memcpy(hdr + 1, data, data_len);
      77             :         else
      78        4419 :                 os_memset(hdr + 1, 0, data_len);
      79             : 
      80       16542 :         if (data_pos)
      81        4404 :                 *data_pos = hdr + 1;
      82             : 
      83       16542 :         return (u8 *) hdr;
      84             : }
      85             : 
      86             : 
      87             : /**
      88             :  * wpa_ether_send - Send Ethernet frame
      89             :  * @wpa_s: Pointer to wpa_supplicant data
      90             :  * @dest: Destination MAC address
      91             :  * @proto: Ethertype in host byte order
      92             :  * @buf: Frame payload starting from IEEE 802.1X header
      93             :  * @len: Frame payload length
      94             :  * Returns: >=0 on success, <0 on failure
      95             :  */
      96       16510 : static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
      97             :                           u16 proto, const u8 *buf, size_t len)
      98             : {
      99             : #ifdef CONFIG_TESTING_OPTIONS
     100       16510 :         if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
     101         345 :                 size_t hex_len = 2 * len + 1;
     102         345 :                 char *hex = os_malloc(hex_len);
     103             : 
     104         345 :                 if (hex == NULL)
     105           0 :                         return -1;
     106         345 :                 wpa_snprintf_hex(hex, hex_len, buf, len);
     107        2070 :                 wpa_msg(wpa_s, MSG_INFO, "EAPOL-TX " MACSTR " %s",
     108        2070 :                         MAC2STR(dest), hex);
     109         345 :                 os_free(hex);
     110         345 :                 return 0;
     111             :         }
     112             : #endif /* CONFIG_TESTING_OPTIONS */
     113             : 
     114       16165 :         if (wpa_s->l2) {
     115       16165 :                 return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
     116             :         }
     117             : 
     118           0 :         return -1;
     119             : }
     120             : #endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
     121             : 
     122             : 
     123             : #ifdef IEEE8021X_EAPOL
     124             : 
     125             : /**
     126             :  * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
     127             :  * @ctx: Pointer to wpa_supplicant data (wpa_s)
     128             :  * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
     129             :  * @buf: EAPOL payload (after IEEE 802.1X header)
     130             :  * @len: EAPOL payload length
     131             :  * Returns: >=0 on success, <0 on failure
     132             :  *
     133             :  * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
     134             :  * to the current Authenticator.
     135             :  */
     136       12094 : static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
     137             :                                      size_t len)
     138             : {
     139       12094 :         struct wpa_supplicant *wpa_s = ctx;
     140             :         u8 *msg, *dst, bssid[ETH_ALEN];
     141             :         size_t msglen;
     142             :         int res;
     143             : 
     144             :         /* TODO: could add l2_packet_sendmsg that allows fragments to avoid
     145             :          * extra copy here */
     146             : 
     147       24187 :         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
     148       12093 :             wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
     149             :                 /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
     150             :                  * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
     151             :                  * machines. */
     152           1 :                 wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
     153             :                            "mode (type=%d len=%lu)", type,
     154             :                            (unsigned long) len);
     155           1 :                 return -1;
     156             :         }
     157             : 
     158       12093 :         if (pmksa_cache_get_current(wpa_s->wpa) &&
     159             :             type == IEEE802_1X_TYPE_EAPOL_START) {
     160             :                 /*
     161             :                  * We were trying to use PMKSA caching and sending EAPOL-Start
     162             :                  * would abort that and trigger full EAPOL authentication.
     163             :                  * However, we've already waited for the AP/Authenticator to
     164             :                  * start 4-way handshake or EAP authentication, and apparently
     165             :                  * it has not done so since the startWhen timer has reached zero
     166             :                  * to get the state machine sending EAPOL-Start. This is not
     167             :                  * really supposed to happen, but an interoperability issue with
     168             :                  * a deployed AP has been identified where the connection fails
     169             :                  * due to that AP failing to operate correctly if PMKID is
     170             :                  * included in the Association Request frame. To work around
     171             :                  * this, assume PMKSA caching failed and try to initiate full
     172             :                  * EAP authentication.
     173             :                  */
     174           0 :                 if (!wpa_s->current_ssid ||
     175           0 :                     wpa_s->current_ssid->eap_workaround) {
     176           0 :                         wpa_printf(MSG_DEBUG,
     177             :                                    "RSN: Timeout on waiting for the AP to initiate 4-way handshake for PMKSA caching or EAP authentication - try to force it to start EAP authentication");
     178             :                 } else {
     179           0 :                         wpa_printf(MSG_DEBUG,
     180             :                                    "RSN: PMKSA caching - do not send EAPOL-Start");
     181           0 :                         return -1;
     182             :                 }
     183             :         }
     184             : 
     185       12093 :         if (is_zero_ether_addr(wpa_s->bssid)) {
     186           0 :                 wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
     187             :                            "EAPOL frame");
     188           0 :                 if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
     189           0 :                     !is_zero_ether_addr(bssid)) {
     190           0 :                         dst = bssid;
     191           0 :                         wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
     192             :                                    " from the driver as the EAPOL destination",
     193           0 :                                    MAC2STR(dst));
     194             :                 } else {
     195           0 :                         dst = wpa_s->last_eapol_src;
     196           0 :                         wpa_printf(MSG_DEBUG, "Using the source address of the"
     197             :                                    " last received EAPOL frame " MACSTR " as "
     198             :                                    "the EAPOL destination",
     199           0 :                                    MAC2STR(dst));
     200             :                 }
     201             :         } else {
     202             :                 /* BSSID was already set (from (Re)Assoc event, so use it as
     203             :                  * the EAPOL destination. */
     204       12093 :                 dst = wpa_s->bssid;
     205             :         }
     206             : 
     207       12093 :         msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
     208       12093 :         if (msg == NULL)
     209           0 :                 return -1;
     210             : 
     211       12093 :         wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
     212       12093 :         wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
     213       12093 :         res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
     214       12093 :         os_free(msg);
     215       12093 :         return res;
     216             : }
     217             : 
     218             : 
     219             : /**
     220             :  * wpa_eapol_set_wep_key - set WEP key for the driver
     221             :  * @ctx: Pointer to wpa_supplicant data (wpa_s)
     222             :  * @unicast: 1 = individual unicast key, 0 = broadcast key
     223             :  * @keyidx: WEP key index (0..3)
     224             :  * @key: Pointer to key data
     225             :  * @keylen: Key length in bytes
     226             :  * Returns: 0 on success or < 0 on error.
     227             :  */
     228          15 : static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
     229             :                                  const u8 *key, size_t keylen)
     230             : {
     231          15 :         struct wpa_supplicant *wpa_s = ctx;
     232          15 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
     233          15 :                 int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
     234             :                         WPA_CIPHER_WEP104;
     235          15 :                 if (unicast)
     236           7 :                         wpa_s->pairwise_cipher = cipher;
     237             :                 else
     238           8 :                         wpa_s->group_cipher = cipher;
     239             :         }
     240          15 :         return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
     241             :                                unicast ? wpa_s->bssid : NULL,
     242             :                                keyidx, unicast, NULL, 0, key, keylen);
     243             : }
     244             : 
     245             : 
     246          75 : static void wpa_supplicant_aborted_cached(void *ctx)
     247             : {
     248          75 :         struct wpa_supplicant *wpa_s = ctx;
     249          75 :         wpa_sm_aborted_cached(wpa_s->wpa);
     250          75 : }
     251             : 
     252             : 
     253        3392 : static const char * result_str(enum eapol_supp_result result)
     254             : {
     255        3392 :         switch (result) {
     256             :         case EAPOL_SUPP_RESULT_FAILURE:
     257         974 :                 return "FAILURE";
     258             :         case EAPOL_SUPP_RESULT_SUCCESS:
     259        2384 :                 return "SUCCESS";
     260             :         case EAPOL_SUPP_RESULT_EXPECTED_FAILURE:
     261          34 :                 return "EXPECTED_FAILURE";
     262             :         }
     263           0 :         return "?";
     264             : }
     265             : 
     266             : 
     267        3392 : static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
     268             :                                     enum eapol_supp_result result,
     269             :                                     void *ctx)
     270             : {
     271        3392 :         struct wpa_supplicant *wpa_s = ctx;
     272             :         int res, pmk_len;
     273             :         u8 pmk[PMK_LEN];
     274             : 
     275        3392 :         wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s",
     276             :                    result_str(result));
     277             : 
     278        3392 :         if (wpas_wps_eapol_cb(wpa_s) > 0)
     279        3833 :                 return;
     280             : 
     281        2951 :         wpa_s->eap_expected_failure = result ==
     282             :                 EAPOL_SUPP_RESULT_EXPECTED_FAILURE;
     283             : 
     284        2951 :         if (result != EAPOL_SUPP_RESULT_SUCCESS) {
     285             :                 /*
     286             :                  * Make sure we do not get stuck here waiting for long EAPOL
     287             :                  * timeout if the AP does not disconnect in case of
     288             :                  * authentication failure.
     289             :                  */
     290         567 :                 wpa_supplicant_req_auth_timeout(wpa_s, 2, 0);
     291             :         } else {
     292        2384 :                 ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src);
     293             :         }
     294             : 
     295        5335 :         if (result != EAPOL_SUPP_RESULT_SUCCESS ||
     296        2384 :             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
     297        2951 :                 return;
     298             : 
     299           0 :         if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
     300           0 :                 return;
     301             : 
     302           0 :         wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
     303             :                    "handshake");
     304             : 
     305           0 :         pmk_len = PMK_LEN;
     306           0 :         if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
     307             : #ifdef CONFIG_IEEE80211R
     308             :                 u8 buf[2 * PMK_LEN];
     309           0 :                 wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for "
     310             :                            "driver-based 4-way hs and FT");
     311           0 :                 res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN);
     312           0 :                 if (res == 0) {
     313           0 :                         os_memcpy(pmk, buf + PMK_LEN, PMK_LEN);
     314           0 :                         os_memset(buf, 0, sizeof(buf));
     315             :                 }
     316             : #else /* CONFIG_IEEE80211R */
     317             :                 res = -1;
     318             : #endif /* CONFIG_IEEE80211R */
     319             :         } else {
     320           0 :                 res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
     321           0 :                 if (res) {
     322             :                         /*
     323             :                          * EAP-LEAP is an exception from other EAP methods: it
     324             :                          * uses only 16-byte PMK.
     325             :                          */
     326           0 :                         res = eapol_sm_get_key(eapol, pmk, 16);
     327           0 :                         pmk_len = 16;
     328             :                 }
     329             :         }
     330             : 
     331           0 :         if (res) {
     332           0 :                 wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
     333             :                            "machines");
     334           0 :                 return;
     335             :         }
     336             : 
     337           0 :         wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way "
     338             :                         "handshake", pmk, pmk_len);
     339             : 
     340           0 :         if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
     341             :                             pmk_len)) {
     342           0 :                 wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
     343             :         }
     344             : 
     345           0 :         wpa_supplicant_cancel_scan(wpa_s);
     346           0 :         wpa_supplicant_cancel_auth_timeout(wpa_s);
     347           0 :         wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
     348             : 
     349             : }
     350             : 
     351             : 
     352          19 : static void wpa_supplicant_notify_eapol_done(void *ctx)
     353             : {
     354          19 :         struct wpa_supplicant *wpa_s = ctx;
     355          19 :         wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
     356          19 :         if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
     357           0 :                 wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
     358             :         } else {
     359          19 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
     360          19 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
     361             :         }
     362          19 : }
     363             : 
     364             : #endif /* IEEE8021X_EAPOL */
     365             : 
     366             : 
     367             : #ifndef CONFIG_NO_WPA
     368             : 
     369           8 : static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
     370             : {
     371           8 :         int ret = 0;
     372           8 :         struct wpa_bss *curr = NULL, *bss;
     373           8 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     374             :         const u8 *ie;
     375             : 
     376           9 :         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
     377           9 :                 if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0)
     378           1 :                         continue;
     379          16 :                 if (ssid == NULL ||
     380          16 :                     ((bss->ssid_len == ssid->ssid_len &&
     381           8 :                       os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) ||
     382           0 :                      ssid->ssid_len == 0)) {
     383           8 :                         curr = bss;
     384           8 :                         break;
     385             :                 }
     386             :         }
     387             : 
     388           8 :         if (curr) {
     389           8 :                 ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE);
     390           8 :                 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
     391           0 :                         ret = -1;
     392             : 
     393           8 :                 ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
     394           8 :                 if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
     395           0 :                         ret = -1;
     396             :         } else {
     397           0 :                 ret = -1;
     398             :         }
     399             : 
     400           8 :         return ret;
     401             : }
     402             : 
     403             : 
     404           8 : static int wpa_supplicant_get_beacon_ie(void *ctx)
     405             : {
     406           8 :         struct wpa_supplicant *wpa_s = ctx;
     407           8 :         if (wpa_get_beacon_ie(wpa_s) == 0) {
     408           8 :                 return 0;
     409             :         }
     410             : 
     411             :         /* No WPA/RSN IE found in the cached scan results. Try to get updated
     412             :          * scan results from the driver. */
     413           0 :         if (wpa_supplicant_update_scan_results(wpa_s) < 0)
     414           0 :                 return -1;
     415             : 
     416           0 :         return wpa_get_beacon_ie(wpa_s);
     417             : }
     418             : 
     419             : 
     420        4449 : static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
     421             :                              const void *data, u16 data_len,
     422             :                              size_t *msg_len, void **data_pos)
     423             : {
     424        4449 :         return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
     425             : }
     426             : 
     427             : 
     428        4417 : static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
     429             :                            const u8 *buf, size_t len)
     430             : {
     431        4417 :         return wpa_ether_send(wpa_s, dest, proto, buf, len);
     432             : }
     433             : 
     434             : 
     435        2383 : static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
     436             : {
     437        2383 :         wpa_supplicant_cancel_auth_timeout(wpa_s);
     438        2383 : }
     439             : 
     440             : 
     441        8947 : static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state)
     442             : {
     443        8947 :         wpa_supplicant_set_state(wpa_s, state);
     444        8947 : }
     445             : 
     446             : 
     447             : /**
     448             :  * wpa_supplicant_get_state - Get the connection state
     449             :  * @wpa_s: Pointer to wpa_supplicant data
     450             :  * Returns: The current connection state (WPA_*)
     451             :  */
     452        4990 : static enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
     453             : {
     454        4990 :         return wpa_s->wpa_state;
     455             : }
     456             : 
     457             : 
     458        4990 : static enum wpa_states _wpa_supplicant_get_state(void *wpa_s)
     459             : {
     460        4990 :         return wpa_supplicant_get_state(wpa_s);
     461             : }
     462             : 
     463             : 
     464          61 : static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
     465             : {
     466          61 :         wpa_supplicant_deauthenticate(wpa_s, reason_code);
     467             :         /* Schedule a scan to make sure we continue looking for networks */
     468          61 :         wpa_supplicant_req_scan(wpa_s, 5, 0);
     469          61 : }
     470             : 
     471             : 
     472        2218 : static void * wpa_supplicant_get_network_ctx(void *wpa_s)
     473             : {
     474        2218 :         return wpa_supplicant_get_ssid(wpa_s);
     475             : }
     476             : 
     477             : 
     478          12 : static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
     479             : {
     480          12 :         struct wpa_supplicant *wpa_s = ctx;
     481          12 :         return wpa_drv_get_bssid(wpa_s, bssid);
     482             : }
     483             : 
     484             : 
     485        5134 : static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg,
     486             :                                   const u8 *addr, int key_idx, int set_tx,
     487             :                                   const u8 *seq, size_t seq_len,
     488             :                                   const u8 *key, size_t key_len)
     489             : {
     490        5134 :         struct wpa_supplicant *wpa_s = _wpa_s;
     491        5134 :         if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
     492             :                 /* Clear the MIC error counter when setting a new PTK. */
     493          28 :                 wpa_s->mic_errors_seen = 0;
     494             :         }
     495             : #ifdef CONFIG_TESTING_GET_GTK
     496             :         if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) &&
     497             :             alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) {
     498             :                 os_memcpy(wpa_s->last_gtk, key, key_len);
     499             :                 wpa_s->last_gtk_len = key_len;
     500             :         }
     501             : #endif /* CONFIG_TESTING_GET_GTK */
     502        5134 :         return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
     503             :                                key, key_len);
     504             : }
     505             : 
     506             : 
     507        4494 : static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
     508             :                                              int protection_type,
     509             :                                              int key_type)
     510             : {
     511        4494 :         return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
     512             :                                           key_type);
     513             : }
     514             : 
     515             : 
     516        1276 : static int wpa_supplicant_add_pmkid(void *wpa_s,
     517             :                                     const u8 *bssid, const u8 *pmkid)
     518             : {
     519        1276 :         return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
     520             : }
     521             : 
     522             : 
     523        1276 : static int wpa_supplicant_remove_pmkid(void *wpa_s,
     524             :                                        const u8 *bssid, const u8 *pmkid)
     525             : {
     526        1276 :         return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid);
     527             : }
     528             : 
     529             : 
     530             : #ifdef CONFIG_IEEE80211R
     531         917 : static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
     532             :                                         const u8 *ies, size_t ies_len)
     533             : {
     534         917 :         struct wpa_supplicant *wpa_s = ctx;
     535         917 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
     536         917 :                 return sme_update_ft_ies(wpa_s, md, ies, ies_len);
     537           0 :         return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
     538             : }
     539             : 
     540             : 
     541         117 : static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
     542             :                                          const u8 *target_ap,
     543             :                                          const u8 *ies, size_t ies_len)
     544             : {
     545         117 :         struct wpa_supplicant *wpa_s = ctx;
     546             :         int ret;
     547             :         u8 *data, *pos;
     548             :         size_t data_len;
     549             : 
     550         117 :         if (action != 1) {
     551           0 :                 wpa_printf(MSG_ERROR, "Unsupported send_ft_action action %d",
     552             :                            action);
     553           0 :                 return -1;
     554             :         }
     555             : 
     556             :         /*
     557             :          * Action frame payload:
     558             :          * Category[1] = 6 (Fast BSS Transition)
     559             :          * Action[1] = 1 (Fast BSS Transition Request)
     560             :          * STA Address
     561             :          * Target AP Address
     562             :          * FT IEs
     563             :          */
     564             : 
     565         117 :         data_len = 2 + 2 * ETH_ALEN + ies_len;
     566         117 :         data = os_malloc(data_len);
     567         117 :         if (data == NULL)
     568           0 :                 return -1;
     569         117 :         pos = data;
     570         117 :         *pos++ = 0x06; /* FT Action category */
     571         117 :         *pos++ = action;
     572         117 :         os_memcpy(pos, wpa_s->own_addr, ETH_ALEN);
     573         117 :         pos += ETH_ALEN;
     574         117 :         os_memcpy(pos, target_ap, ETH_ALEN);
     575         117 :         pos += ETH_ALEN;
     576         117 :         os_memcpy(pos, ies, ies_len);
     577             : 
     578         117 :         ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
     579         117 :                                   wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid,
     580             :                                   data, data_len, 0);
     581         117 :         os_free(data);
     582             : 
     583         117 :         return ret;
     584             : }
     585             : 
     586             : 
     587         230 : static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
     588             : {
     589         230 :         struct wpa_supplicant *wpa_s = ctx;
     590             :         struct wpa_driver_auth_params params;
     591             :         struct wpa_bss *bss;
     592             : 
     593         230 :         bss = wpa_bss_get_bssid(wpa_s, target_ap);
     594         230 :         if (bss == NULL)
     595           0 :                 return -1;
     596             : 
     597         230 :         os_memset(&params, 0, sizeof(params));
     598         230 :         params.bssid = target_ap;
     599         230 :         params.freq = bss->freq;
     600         230 :         params.ssid = bss->ssid;
     601         230 :         params.ssid_len = bss->ssid_len;
     602         230 :         params.auth_alg = WPA_AUTH_ALG_FT;
     603         230 :         params.local_state_change = 1;
     604         230 :         return wpa_drv_authenticate(wpa_s, &params);
     605             : }
     606             : #endif /* CONFIG_IEEE80211R */
     607             : 
     608             : 
     609             : #ifdef CONFIG_TDLS
     610             : 
     611         677 : static int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported,
     612             :                                         int *tdls_ext_setup,
     613             :                                         int *tdls_chan_switch)
     614             : {
     615         677 :         struct wpa_supplicant *wpa_s = ctx;
     616             : 
     617         677 :         *tdls_supported = 0;
     618         677 :         *tdls_ext_setup = 0;
     619         677 :         *tdls_chan_switch = 0;
     620             : 
     621         677 :         if (!wpa_s->drv_capa_known)
     622          47 :                 return -1;
     623             : 
     624         630 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)
     625         621 :                 *tdls_supported = 1;
     626             : 
     627         630 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP)
     628         621 :                 *tdls_ext_setup = 1;
     629             : 
     630         630 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH)
     631         621 :                 *tdls_chan_switch = 1;
     632             : 
     633         630 :         return 0;
     634             : }
     635             : 
     636             : 
     637         143 : static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
     638             :                                          u8 action_code, u8 dialog_token,
     639             :                                          u16 status_code, u32 peer_capab,
     640             :                                          int initiator, const u8 *buf,
     641             :                                          size_t len)
     642             : {
     643         143 :         struct wpa_supplicant *wpa_s = ctx;
     644         143 :         return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
     645             :                                       status_code, peer_capab, initiator, buf,
     646             :                                       len);
     647             : }
     648             : 
     649             : 
     650         124 : static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
     651             : {
     652         124 :         struct wpa_supplicant *wpa_s = ctx;
     653         124 :         return wpa_drv_tdls_oper(wpa_s, oper, peer);
     654             : }
     655             : 
     656             : 
     657         123 : static int wpa_supplicant_tdls_peer_addset(
     658             :         void *ctx, const u8 *peer, int add, u16 aid, u16 capability,
     659             :         const u8 *supp_rates, size_t supp_rates_len,
     660             :         const struct ieee80211_ht_capabilities *ht_capab,
     661             :         const struct ieee80211_vht_capabilities *vht_capab,
     662             :         u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
     663             :         const u8 *supp_channels, size_t supp_channels_len,
     664             :         const u8 *supp_oper_classes, size_t supp_oper_classes_len)
     665             : {
     666         123 :         struct wpa_supplicant *wpa_s = ctx;
     667             :         struct hostapd_sta_add_params params;
     668             : 
     669         123 :         os_memset(&params, 0, sizeof(params));
     670             : 
     671         123 :         params.addr = peer;
     672         123 :         params.aid = aid;
     673         123 :         params.capability = capability;
     674         123 :         params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
     675             : 
     676             :         /*
     677             :          * Don't rely only on qosinfo for WMM capability. It may be 0 even when
     678             :          * present. Allow the WMM IE to also indicate QoS support.
     679             :          */
     680         123 :         if (wmm || qosinfo)
     681          88 :                 params.flags |= WPA_STA_WMM;
     682             : 
     683         123 :         params.ht_capabilities = ht_capab;
     684         123 :         params.vht_capabilities = vht_capab;
     685         123 :         params.qosinfo = qosinfo;
     686         123 :         params.listen_interval = 0;
     687         123 :         params.supp_rates = supp_rates;
     688         123 :         params.supp_rates_len = supp_rates_len;
     689         123 :         params.set = !add;
     690         123 :         params.ext_capab = ext_capab;
     691         123 :         params.ext_capab_len = ext_capab_len;
     692         123 :         params.supp_channels = supp_channels;
     693         123 :         params.supp_channels_len = supp_channels_len;
     694         123 :         params.supp_oper_classes = supp_oper_classes;
     695         123 :         params.supp_oper_classes_len = supp_oper_classes_len;
     696             : 
     697         123 :         return wpa_drv_sta_add(wpa_s, &params);
     698             : }
     699             : 
     700             : 
     701           1 : static int wpa_supplicant_tdls_enable_channel_switch(
     702             :         void *ctx, const u8 *addr, u8 oper_class,
     703             :         const struct hostapd_freq_params *params)
     704             : {
     705           1 :         struct wpa_supplicant *wpa_s = ctx;
     706             : 
     707           1 :         return wpa_drv_tdls_enable_channel_switch(wpa_s, addr, oper_class,
     708             :                                                   params);
     709             : }
     710             : 
     711             : 
     712           1 : static int wpa_supplicant_tdls_disable_channel_switch(void *ctx, const u8 *addr)
     713             : {
     714           1 :         struct wpa_supplicant *wpa_s = ctx;
     715             : 
     716           1 :         return wpa_drv_tdls_disable_channel_switch(wpa_s, addr);
     717             : }
     718             : 
     719             : #endif /* CONFIG_TDLS */
     720             : 
     721             : #endif /* CONFIG_NO_WPA */
     722             : 
     723             : 
     724          85 : enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
     725             : {
     726          85 :         if (os_strcmp(field, "IDENTITY") == 0)
     727           7 :                 return WPA_CTRL_REQ_EAP_IDENTITY;
     728          78 :         else if (os_strcmp(field, "PASSWORD") == 0)
     729           9 :                 return WPA_CTRL_REQ_EAP_PASSWORD;
     730          69 :         else if (os_strcmp(field, "NEW_PASSWORD") == 0)
     731          14 :                 return WPA_CTRL_REQ_EAP_NEW_PASSWORD;
     732          55 :         else if (os_strcmp(field, "PIN") == 0)
     733           2 :                 return WPA_CTRL_REQ_EAP_PIN;
     734          53 :         else if (os_strcmp(field, "OTP") == 0)
     735           4 :                 return WPA_CTRL_REQ_EAP_OTP;
     736          49 :         else if (os_strcmp(field, "PASSPHRASE") == 0)
     737           3 :                 return WPA_CTRL_REQ_EAP_PASSPHRASE;
     738          46 :         else if (os_strcmp(field, "SIM") == 0)
     739          34 :                 return WPA_CTRL_REQ_SIM;
     740          12 :         else if (os_strcmp(field, "PSK_PASSPHRASE") == 0)
     741           3 :                 return WPA_CTRL_REQ_PSK_PASSPHRASE;
     742           9 :         else if (os_strcmp(field, "EXT_CERT_CHECK") == 0)
     743           8 :                 return WPA_CTRL_REQ_EXT_CERT_CHECK;
     744           1 :         return WPA_CTRL_REQ_UNKNOWN;
     745             : }
     746             : 
     747             : 
     748         177 : const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
     749             :                                                const char *default_txt,
     750             :                                                const char **txt)
     751             : {
     752         177 :         const char *ret = NULL;
     753             : 
     754         177 :         *txt = default_txt;
     755             : 
     756         177 :         switch (field) {
     757             :         case WPA_CTRL_REQ_EAP_IDENTITY:
     758          18 :                 *txt = "Identity";
     759          18 :                 ret = "IDENTITY";
     760          18 :                 break;
     761             :         case WPA_CTRL_REQ_EAP_PASSWORD:
     762          32 :                 *txt = "Password";
     763          32 :                 ret = "PASSWORD";
     764          32 :                 break;
     765             :         case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
     766          24 :                 *txt = "New Password";
     767          24 :                 ret = "NEW_PASSWORD";
     768          24 :                 break;
     769             :         case WPA_CTRL_REQ_EAP_PIN:
     770           2 :                 *txt = "PIN";
     771           2 :                 ret = "PIN";
     772           2 :                 break;
     773             :         case WPA_CTRL_REQ_EAP_OTP:
     774           4 :                 ret = "OTP";
     775           4 :                 break;
     776             :         case WPA_CTRL_REQ_EAP_PASSPHRASE:
     777          12 :                 *txt = "Private key passphrase";
     778          12 :                 ret = "PASSPHRASE";
     779          12 :                 break;
     780             :         case WPA_CTRL_REQ_SIM:
     781          64 :                 ret = "SIM";
     782          64 :                 break;
     783             :         case WPA_CTRL_REQ_PSK_PASSPHRASE:
     784           5 :                 *txt = "PSK or passphrase";
     785           5 :                 ret = "PSK_PASSPHRASE";
     786           5 :                 break;
     787             :         case WPA_CTRL_REQ_EXT_CERT_CHECK:
     788          16 :                 *txt = "External server certificate validation";
     789          16 :                 ret = "EXT_CERT_CHECK";
     790          16 :                 break;
     791             :         default:
     792           0 :                 break;
     793             :         }
     794             : 
     795             :         /* txt needs to be something */
     796         177 :         if (*txt == NULL) {
     797           0 :                 wpa_printf(MSG_WARNING, "No message for request %d", field);
     798           0 :                 ret = NULL;
     799             :         }
     800             : 
     801         177 :         return ret;
     802             : }
     803             : 
     804             : 
     805          89 : void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
     806             :                         const char *field_name, const char *txt)
     807             : {
     808             :         char *buf;
     809             :         size_t buflen;
     810             :         int len;
     811             : 
     812          89 :         buflen = 100 + os_strlen(txt) + ssid->ssid_len;
     813          89 :         buf = os_malloc(buflen);
     814          89 :         if (buf == NULL)
     815           0 :                 return;
     816          89 :         len = os_snprintf(buf, buflen, "%s-%d:%s needed for SSID ",
     817             :                           field_name, ssid->id, txt);
     818          89 :         if (os_snprintf_error(buflen, len)) {
     819           0 :                 os_free(buf);
     820           0 :                 return;
     821             :         }
     822          89 :         if (ssid->ssid && buflen > len + ssid->ssid_len) {
     823          89 :                 os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
     824          89 :                 len += ssid->ssid_len;
     825          89 :                 buf[len] = '\0';
     826             :         }
     827          89 :         buf[buflen - 1] = '\0';
     828          89 :         wpa_msg(wpa_s, MSG_INFO, WPA_CTRL_REQ "%s", buf);
     829          89 :         os_free(buf);
     830             : }
     831             : 
     832             : 
     833             : #ifdef IEEE8021X_EAPOL
     834             : #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
     835          86 : static void wpa_supplicant_eap_param_needed(void *ctx,
     836             :                                             enum wpa_ctrl_req_type field,
     837             :                                             const char *default_txt)
     838             : {
     839          86 :         struct wpa_supplicant *wpa_s = ctx;
     840          86 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     841          86 :         const char *field_name, *txt = NULL;
     842             : 
     843          86 :         if (ssid == NULL)
     844           0 :                 return;
     845             : 
     846          86 :         if (field == WPA_CTRL_REQ_EXT_CERT_CHECK)
     847           8 :                 ssid->eap.pending_ext_cert_check = PENDING_CHECK;
     848          86 :         wpas_notify_network_request(wpa_s, ssid, field, default_txt);
     849             : 
     850          86 :         field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
     851             :                                                        &txt);
     852          86 :         if (field_name == NULL) {
     853           0 :                 wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
     854             :                            field);
     855           0 :                 return;
     856             :         }
     857             : 
     858          86 :         wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name);
     859             : 
     860          86 :         wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
     861             : }
     862             : #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
     863             : #define wpa_supplicant_eap_param_needed NULL
     864             : #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
     865             : 
     866             : 
     867             : #ifdef CONFIG_EAP_PROXY
     868             : static void wpa_supplicant_eap_proxy_cb(void *ctx)
     869             : {
     870             :         struct wpa_supplicant *wpa_s = ctx;
     871             :         size_t len;
     872             : 
     873             :         wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol,
     874             :                                                      wpa_s->imsi, &len);
     875             :         if (wpa_s->mnc_len > 0) {
     876             :                 wpa_s->imsi[len] = '\0';
     877             :                 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
     878             :                            wpa_s->imsi, wpa_s->mnc_len);
     879             :         } else {
     880             :                 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
     881             :         }
     882             : }
     883             : #endif /* CONFIG_EAP_PROXY */
     884             : 
     885             : 
     886        9611 : static void wpa_supplicant_port_cb(void *ctx, int authorized)
     887             : {
     888        9611 :         struct wpa_supplicant *wpa_s = ctx;
     889             : #ifdef CONFIG_AP
     890        9611 :         if (wpa_s->ap_iface) {
     891           0 :                 wpa_printf(MSG_DEBUG, "AP mode active - skip EAPOL Supplicant "
     892             :                            "port status: %s",
     893             :                            authorized ? "Authorized" : "Unauthorized");
     894        9611 :                 return;
     895             :         }
     896             : #endif /* CONFIG_AP */
     897        9611 :         wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s",
     898             :                    authorized ? "Authorized" : "Unauthorized");
     899        9611 :         wpa_drv_set_supp_port(wpa_s, authorized);
     900             : }
     901             : 
     902             : 
     903         941 : static void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject,
     904             :                                    const char *altsubject[], int num_altsubject,
     905             :                                    const char *cert_hash,
     906             :                                    const struct wpabuf *cert)
     907             : {
     908         941 :         struct wpa_supplicant *wpa_s = ctx;
     909             : 
     910         941 :         wpas_notify_certification(wpa_s, depth, subject, altsubject,
     911             :                                   num_altsubject, cert_hash, cert);
     912         941 : }
     913             : 
     914             : 
     915        8607 : static void wpa_supplicant_status_cb(void *ctx, const char *status,
     916             :                                      const char *parameter)
     917             : {
     918        8607 :         struct wpa_supplicant *wpa_s = ctx;
     919             : 
     920        8607 :         wpas_notify_eap_status(wpa_s, status, parameter);
     921        8607 : }
     922             : 
     923             : 
     924          86 : static void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len)
     925             : {
     926          86 :         struct wpa_supplicant *wpa_s = ctx;
     927             :         char *str;
     928             :         int res;
     929             : 
     930          86 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity",
     931             :                           id, len);
     932             : 
     933          86 :         if (wpa_s->current_ssid == NULL)
     934           0 :                 return;
     935             : 
     936          86 :         if (id == NULL) {
     937           5 :                 if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
     938             :                                    "NULL", 0) < 0)
     939           0 :                         return;
     940             :         } else {
     941          81 :                 str = os_malloc(len * 2 + 1);
     942          81 :                 if (str == NULL)
     943           1 :                         return;
     944          80 :                 wpa_snprintf_hex(str, len * 2 + 1, id, len);
     945          80 :                 res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
     946             :                                      str, 0);
     947          80 :                 os_free(str);
     948          80 :                 if (res < 0)
     949           1 :                         return;
     950             :         }
     951             : 
     952          84 :         if (wpa_s->conf->update_config) {
     953           0 :                 res = wpa_config_write(wpa_s->confname, wpa_s->conf);
     954           0 :                 if (res) {
     955           0 :                         wpa_printf(MSG_DEBUG, "Failed to update config after "
     956             :                                    "anonymous_id update");
     957             :                 }
     958             :         }
     959             : }
     960             : #endif /* IEEE8021X_EAPOL */
     961             : 
     962             : 
     963         707 : int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
     964             : {
     965             : #ifdef IEEE8021X_EAPOL
     966             :         struct eapol_ctx *ctx;
     967         707 :         ctx = os_zalloc(sizeof(*ctx));
     968         707 :         if (ctx == NULL) {
     969           1 :                 wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
     970           1 :                 return -1;
     971             :         }
     972             : 
     973         706 :         ctx->ctx = wpa_s;
     974         706 :         ctx->msg_ctx = wpa_s;
     975         706 :         ctx->eapol_send_ctx = wpa_s;
     976         706 :         ctx->preauth = 0;
     977         706 :         ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
     978         706 :         ctx->eapol_send = wpa_supplicant_eapol_send;
     979         706 :         ctx->set_wep_key = wpa_eapol_set_wep_key;
     980             : #ifndef CONFIG_NO_CONFIG_BLOBS
     981         706 :         ctx->set_config_blob = wpa_supplicant_set_config_blob;
     982         706 :         ctx->get_config_blob = wpa_supplicant_get_config_blob;
     983             : #endif /* CONFIG_NO_CONFIG_BLOBS */
     984         706 :         ctx->aborted_cached = wpa_supplicant_aborted_cached;
     985         706 :         ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
     986         706 :         ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
     987         706 :         ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
     988         706 :         ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers;
     989         706 :         ctx->wps = wpa_s->wps;
     990         706 :         ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
     991             : #ifdef CONFIG_EAP_PROXY
     992             :         ctx->eap_proxy_cb = wpa_supplicant_eap_proxy_cb;
     993             : #endif /* CONFIG_EAP_PROXY */
     994         706 :         ctx->port_cb = wpa_supplicant_port_cb;
     995         706 :         ctx->cb = wpa_supplicant_eapol_cb;
     996         706 :         ctx->cert_cb = wpa_supplicant_cert_cb;
     997         706 :         ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
     998         706 :         ctx->status_cb = wpa_supplicant_status_cb;
     999         706 :         ctx->set_anon_id = wpa_supplicant_set_anon_id;
    1000         706 :         ctx->cb_ctx = wpa_s;
    1001         706 :         wpa_s->eapol = eapol_sm_init(ctx);
    1002         706 :         if (wpa_s->eapol == NULL) {
    1003           4 :                 os_free(ctx);
    1004           4 :                 wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
    1005             :                            "machines.");
    1006           4 :                 return -1;
    1007             :         }
    1008             : #endif /* IEEE8021X_EAPOL */
    1009             : 
    1010         702 :         return 0;
    1011             : }
    1012             : 
    1013             : 
    1014             : #ifndef CONFIG_NO_WPA
    1015        2156 : static void wpa_supplicant_set_rekey_offload(void *ctx,
    1016             :                                              const u8 *kek, size_t kek_len,
    1017             :                                              const u8 *kck, size_t kck_len,
    1018             :                                              const u8 *replay_ctr)
    1019             : {
    1020        2156 :         struct wpa_supplicant *wpa_s = ctx;
    1021             : 
    1022        2156 :         wpa_drv_set_rekey_info(wpa_s, kek, kek_len, kck, kck_len, replay_ctr);
    1023        2156 : }
    1024             : 
    1025             : 
    1026        1208 : static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk,
    1027             :                                            size_t pmk_len)
    1028             : {
    1029        1208 :         struct wpa_supplicant *wpa_s = ctx;
    1030             : 
    1031        2416 :         if (wpa_s->conf->key_mgmt_offload &&
    1032        1208 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
    1033           0 :                 return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0,
    1034             :                                        NULL, 0, pmk, pmk_len);
    1035             :         else
    1036        1208 :                 return 0;
    1037             : }
    1038             : #endif /* CONFIG_NO_WPA */
    1039             : 
    1040             : 
    1041         710 : int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
    1042             : {
    1043             : #ifndef CONFIG_NO_WPA
    1044             :         struct wpa_sm_ctx *ctx;
    1045         710 :         ctx = os_zalloc(sizeof(*ctx));
    1046         710 :         if (ctx == NULL) {
    1047           1 :                 wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
    1048           1 :                 return -1;
    1049             :         }
    1050             : 
    1051         709 :         ctx->ctx = wpa_s;
    1052         709 :         ctx->msg_ctx = wpa_s;
    1053         709 :         ctx->set_state = _wpa_supplicant_set_state;
    1054         709 :         ctx->get_state = _wpa_supplicant_get_state;
    1055         709 :         ctx->deauthenticate = _wpa_supplicant_deauthenticate;
    1056         709 :         ctx->set_key = wpa_supplicant_set_key;
    1057         709 :         ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
    1058         709 :         ctx->get_bssid = wpa_supplicant_get_bssid;
    1059         709 :         ctx->ether_send = _wpa_ether_send;
    1060         709 :         ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
    1061         709 :         ctx->alloc_eapol = _wpa_alloc_eapol;
    1062         709 :         ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
    1063         709 :         ctx->add_pmkid = wpa_supplicant_add_pmkid;
    1064         709 :         ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
    1065             : #ifndef CONFIG_NO_CONFIG_BLOBS
    1066         709 :         ctx->set_config_blob = wpa_supplicant_set_config_blob;
    1067         709 :         ctx->get_config_blob = wpa_supplicant_get_config_blob;
    1068             : #endif /* CONFIG_NO_CONFIG_BLOBS */
    1069         709 :         ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
    1070             : #ifdef CONFIG_IEEE80211R
    1071         709 :         ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
    1072         709 :         ctx->send_ft_action = wpa_supplicant_send_ft_action;
    1073         709 :         ctx->mark_authenticated = wpa_supplicant_mark_authenticated;
    1074             : #endif /* CONFIG_IEEE80211R */
    1075             : #ifdef CONFIG_TDLS
    1076         709 :         ctx->tdls_get_capa = wpa_supplicant_tdls_get_capa;
    1077         709 :         ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt;
    1078         709 :         ctx->tdls_oper = wpa_supplicant_tdls_oper;
    1079         709 :         ctx->tdls_peer_addset = wpa_supplicant_tdls_peer_addset;
    1080         709 :         ctx->tdls_enable_channel_switch =
    1081             :                 wpa_supplicant_tdls_enable_channel_switch;
    1082         709 :         ctx->tdls_disable_channel_switch =
    1083             :                 wpa_supplicant_tdls_disable_channel_switch;
    1084             : #endif /* CONFIG_TDLS */
    1085         709 :         ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
    1086         709 :         ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk;
    1087             : 
    1088         709 :         wpa_s->wpa = wpa_sm_init(ctx);
    1089         709 :         if (wpa_s->wpa == NULL) {
    1090           2 :                 wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
    1091             :                            "machine");
    1092           2 :                 os_free(ctx);
    1093           2 :                 return -1;
    1094             :         }
    1095             : #endif /* CONFIG_NO_WPA */
    1096             : 
    1097         707 :         return 0;
    1098             : }
    1099             : 
    1100             : 
    1101        4989 : void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
    1102             :                                         struct wpa_ssid *ssid)
    1103             : {
    1104             :         struct rsn_supp_config conf;
    1105        4989 :         if (ssid) {
    1106        4989 :                 os_memset(&conf, 0, sizeof(conf));
    1107        4989 :                 conf.network_ctx = ssid;
    1108        4989 :                 conf.peerkey_enabled = ssid->peerkey;
    1109        4989 :                 conf.allowed_pairwise_cipher = ssid->pairwise_cipher;
    1110             : #ifdef IEEE8021X_EAPOL
    1111        9978 :                 conf.proactive_key_caching = ssid->proactive_key_caching < 0 ?
    1112        4989 :                         wpa_s->conf->okc : ssid->proactive_key_caching;
    1113        4989 :                 conf.eap_workaround = ssid->eap_workaround;
    1114        4989 :                 conf.eap_conf_ctx = &ssid->eap;
    1115             : #endif /* IEEE8021X_EAPOL */
    1116        4989 :                 conf.ssid = ssid->ssid;
    1117        4989 :                 conf.ssid_len = ssid->ssid_len;
    1118        4989 :                 conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey;
    1119             : #ifdef CONFIG_P2P
    1120        5519 :                 if (ssid->p2p_group && wpa_s->current_bss &&
    1121         530 :                     !wpa_s->p2p_disable_ip_addr_req) {
    1122             :                         struct wpabuf *p2p;
    1123         528 :                         p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
    1124             :                                                           P2P_IE_VENDOR_TYPE);
    1125         528 :                         if (p2p) {
    1126             :                                 u8 group_capab;
    1127         526 :                                 group_capab = p2p_get_group_capab(p2p);
    1128         526 :                                 if (group_capab &
    1129             :                                     P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION)
    1130         210 :                                         conf.p2p = 1;
    1131         526 :                                 wpabuf_free(p2p);
    1132             :                         }
    1133             :                 }
    1134             : #endif /* CONFIG_P2P */
    1135        4989 :                 conf.wpa_rsc_relaxation = wpa_s->conf->wpa_rsc_relaxation;
    1136             :         }
    1137        4989 :         wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
    1138        4989 : }

Generated by: LCOV version 1.10