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 1393793999 Lines: 818 1243 65.8 %
Date: 2014-03-02 Functions: 55 64 85.9 %
Branches: 452 781 57.9 %

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

Generated by: LCOV version 1.9