LCOV - code coverage report
Current view: top level - src/ap - wpa_auth.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 1132 1572 72.0 %
Date: 2014-03-02 Functions: 85 103 82.5 %
Branches: 561 941 59.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * IEEE 802.11 RSN / WPA Authenticator
       3                 :            :  * Copyright (c) 2004-2013, 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 "utils/includes.h"
      10                 :            : 
      11                 :            : #include "utils/common.h"
      12                 :            : #include "utils/eloop.h"
      13                 :            : #include "utils/state_machine.h"
      14                 :            : #include "utils/bitfield.h"
      15                 :            : #include "common/ieee802_11_defs.h"
      16                 :            : #include "crypto/aes_wrap.h"
      17                 :            : #include "crypto/crypto.h"
      18                 :            : #include "crypto/sha1.h"
      19                 :            : #include "crypto/sha256.h"
      20                 :            : #include "crypto/random.h"
      21                 :            : #include "eapol_auth/eapol_auth_sm.h"
      22                 :            : #include "ap_config.h"
      23                 :            : #include "ieee802_11.h"
      24                 :            : #include "wpa_auth.h"
      25                 :            : #include "pmksa_cache_auth.h"
      26                 :            : #include "wpa_auth_i.h"
      27                 :            : #include "wpa_auth_ie.h"
      28                 :            : 
      29                 :            : #define STATE_MACHINE_DATA struct wpa_state_machine
      30                 :            : #define STATE_MACHINE_DEBUG_PREFIX "WPA"
      31                 :            : #define STATE_MACHINE_ADDR sm->addr
      32                 :            : 
      33                 :            : 
      34                 :            : static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);
      35                 :            : static int wpa_sm_step(struct wpa_state_machine *sm);
      36                 :            : static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);
      37                 :            : static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);
      38                 :            : static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
      39                 :            :                               struct wpa_group *group);
      40                 :            : static void wpa_request_new_ptk(struct wpa_state_machine *sm);
      41                 :            : static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
      42                 :            :                           struct wpa_group *group);
      43                 :            : static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
      44                 :            :                                        struct wpa_group *group);
      45                 :            : 
      46                 :            : static const u32 dot11RSNAConfigGroupUpdateCount = 4;
      47                 :            : static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
      48                 :            : static const u32 eapol_key_timeout_first = 100; /* ms */
      49                 :            : static const u32 eapol_key_timeout_subseq = 1000; /* ms */
      50                 :            : static const u32 eapol_key_timeout_first_group = 500; /* ms */
      51                 :            : 
      52                 :            : /* TODO: make these configurable */
      53                 :            : static const int dot11RSNAConfigPMKLifetime = 43200;
      54                 :            : static const int dot11RSNAConfigPMKReauthThreshold = 70;
      55                 :            : static const int dot11RSNAConfigSATimeout = 60;
      56                 :            : 
      57                 :            : 
      58                 :          0 : static inline int wpa_auth_mic_failure_report(
      59                 :            :         struct wpa_authenticator *wpa_auth, const u8 *addr)
      60                 :            : {
      61         [ #  # ]:          0 :         if (wpa_auth->cb.mic_failure_report)
      62                 :          0 :                 return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
      63                 :          0 :         return 0;
      64                 :            : }
      65                 :            : 
      66                 :            : 
      67                 :       5134 : static inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth,
      68                 :            :                                       const u8 *addr, wpa_eapol_variable var,
      69                 :            :                                       int value)
      70                 :            : {
      71         [ +  - ]:       5134 :         if (wpa_auth->cb.set_eapol)
      72                 :       5134 :                 wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value);
      73                 :       5134 : }
      74                 :            : 
      75                 :            : 
      76                 :       3389 : static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
      77                 :            :                                      const u8 *addr, wpa_eapol_variable var)
      78                 :            : {
      79         [ -  + ]:       3389 :         if (wpa_auth->cb.get_eapol == NULL)
      80                 :          0 :                 return -1;
      81                 :       3389 :         return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var);
      82                 :            : }
      83                 :            : 
      84                 :            : 
      85                 :        753 : static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
      86                 :            :                                           const u8 *addr,
      87                 :            :                                           const u8 *p2p_dev_addr,
      88                 :            :                                           const u8 *prev_psk)
      89                 :            : {
      90         [ -  + ]:        753 :         if (wpa_auth->cb.get_psk == NULL)
      91                 :          0 :                 return NULL;
      92                 :        753 :         return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr,
      93                 :            :                                     prev_psk);
      94                 :            : }
      95                 :            : 
      96                 :            : 
      97                 :        175 : static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
      98                 :            :                                    const u8 *addr, u8 *msk, size_t *len)
      99                 :            : {
     100         [ -  + ]:        175 :         if (wpa_auth->cb.get_msk == NULL)
     101                 :          0 :                 return -1;
     102                 :        175 :         return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len);
     103                 :            : }
     104                 :            : 
     105                 :            : 
     106                 :       3567 : static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
     107                 :            :                                    int vlan_id,
     108                 :            :                                    enum wpa_alg alg, const u8 *addr, int idx,
     109                 :            :                                    u8 *key, size_t key_len)
     110                 :            : {
     111         [ -  + ]:       3567 :         if (wpa_auth->cb.set_key == NULL)
     112                 :          0 :                 return -1;
     113                 :       3567 :         return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
     114                 :            :                                     key, key_len);
     115                 :            : }
     116                 :            : 
     117                 :            : 
     118                 :        431 : static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
     119                 :            :                                       const u8 *addr, int idx, u8 *seq)
     120                 :            : {
     121         [ +  + ]:        431 :         if (wpa_auth->cb.get_seqnum == NULL)
     122                 :          2 :                 return -1;
     123                 :        431 :         return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
     124                 :            : }
     125                 :            : 
     126                 :            : 
     127                 :            : static inline int
     128                 :        848 : wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
     129                 :            :                     const u8 *data, size_t data_len, int encrypt)
     130                 :            : {
     131         [ -  + ]:        848 :         if (wpa_auth->cb.send_eapol == NULL)
     132                 :          0 :                 return -1;
     133                 :        848 :         return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len,
     134                 :            :                                        encrypt);
     135                 :            : }
     136                 :            : 
     137                 :            : 
     138                 :         60 : int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
     139                 :            :                           int (*cb)(struct wpa_state_machine *sm, void *ctx),
     140                 :            :                           void *cb_ctx)
     141                 :            : {
     142         [ -  + ]:         60 :         if (wpa_auth->cb.for_each_sta == NULL)
     143                 :          0 :                 return 0;
     144                 :         60 :         return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx);
     145                 :            : }
     146                 :            : 
     147                 :            : 
     148                 :          1 : int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
     149                 :            :                            int (*cb)(struct wpa_authenticator *a, void *ctx),
     150                 :            :                            void *cb_ctx)
     151                 :            : {
     152         [ -  + ]:          1 :         if (wpa_auth->cb.for_each_auth == NULL)
     153                 :          0 :                 return 0;
     154                 :          1 :         return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx);
     155                 :            : }
     156                 :            : 
     157                 :            : 
     158                 :       3405 : void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
     159                 :            :                      logger_level level, const char *txt)
     160                 :            : {
     161         [ -  + ]:       3405 :         if (wpa_auth->cb.logger == NULL)
     162                 :       3405 :                 return;
     163                 :       3405 :         wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt);
     164                 :            : }
     165                 :            : 
     166                 :            : 
     167                 :       2087 : void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
     168                 :            :                       logger_level level, const char *fmt, ...)
     169                 :            : {
     170                 :            :         char *format;
     171                 :            :         int maxlen;
     172                 :            :         va_list ap;
     173                 :            : 
     174         [ -  + ]:       2087 :         if (wpa_auth->cb.logger == NULL)
     175                 :          0 :                 return;
     176                 :            : 
     177                 :       2087 :         maxlen = os_strlen(fmt) + 100;
     178                 :       2087 :         format = os_malloc(maxlen);
     179         [ -  + ]:       2087 :         if (!format)
     180                 :          0 :                 return;
     181                 :            : 
     182                 :       2087 :         va_start(ap, fmt);
     183                 :       2087 :         vsnprintf(format, maxlen, fmt, ap);
     184                 :       2087 :         va_end(ap);
     185                 :            : 
     186                 :       2087 :         wpa_auth_logger(wpa_auth, addr, level, format);
     187                 :            : 
     188                 :       2087 :         os_free(format);
     189                 :            : }
     190                 :            : 
     191                 :            : 
     192                 :          7 : static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
     193                 :            :                                const u8 *addr)
     194                 :            : {
     195         [ -  + ]:          7 :         if (wpa_auth->cb.disconnect == NULL)
     196                 :          7 :                 return;
     197                 :          7 :         wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
     198                 :          7 :         wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,
     199                 :            :                                 WLAN_REASON_PREV_AUTH_NOT_VALID);
     200                 :            : }
     201                 :            : 
     202                 :            : 
     203                 :       2484 : static int wpa_use_aes_cmac(struct wpa_state_machine *sm)
     204                 :            : {
     205                 :       2484 :         int ret = 0;
     206                 :            : #ifdef CONFIG_IEEE80211R
     207         [ +  + ]:       2484 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
     208                 :         48 :                 ret = 1;
     209                 :            : #endif /* CONFIG_IEEE80211R */
     210                 :            : #ifdef CONFIG_IEEE80211W
     211         [ +  + ]:       2484 :         if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt))
     212                 :         52 :                 ret = 1;
     213                 :            : #endif /* CONFIG_IEEE80211W */
     214         [ +  + ]:       2484 :         if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN)
     215                 :          4 :                 ret = 1;
     216                 :       2484 :         return ret;
     217                 :            : }
     218                 :            : 
     219                 :            : 
     220                 :          0 : static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx)
     221                 :            : {
     222                 :          0 :         struct wpa_authenticator *wpa_auth = eloop_ctx;
     223                 :            : 
     224         [ #  # ]:          0 :         if (random_get_bytes(wpa_auth->group->GMK, WPA_GMK_LEN)) {
     225                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
     226                 :            :                            "initialization.");
     227                 :            :         } else {
     228                 :          0 :                 wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd");
     229                 :          0 :                 wpa_hexdump_key(MSG_DEBUG, "GMK",
     230                 :          0 :                                 wpa_auth->group->GMK, WPA_GMK_LEN);
     231                 :            :         }
     232                 :            : 
     233         [ #  # ]:          0 :         if (wpa_auth->conf.wpa_gmk_rekey) {
     234                 :          0 :                 eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,
     235                 :            :                                        wpa_rekey_gmk, wpa_auth, NULL);
     236                 :            :         }
     237                 :          0 : }
     238                 :            : 
     239                 :            : 
     240                 :          0 : static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
     241                 :            : {
     242                 :          0 :         struct wpa_authenticator *wpa_auth = eloop_ctx;
     243                 :            :         struct wpa_group *group;
     244                 :            : 
     245                 :          0 :         wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK");
     246         [ #  # ]:          0 :         for (group = wpa_auth->group; group; group = group->next) {
     247                 :          0 :                 group->GTKReKey = TRUE;
     248                 :            :                 do {
     249                 :          0 :                         group->changed = FALSE;
     250                 :          0 :                         wpa_group_sm_step(wpa_auth, group);
     251         [ #  # ]:          0 :                 } while (group->changed);
     252                 :            :         }
     253                 :            : 
     254         [ #  # ]:          0 :         if (wpa_auth->conf.wpa_group_rekey) {
     255                 :          0 :                 eloop_register_timeout(wpa_auth->conf.wpa_group_rekey,
     256                 :            :                                        0, wpa_rekey_gtk, wpa_auth, NULL);
     257                 :            :         }
     258                 :          0 : }
     259                 :            : 
     260                 :            : 
     261                 :          0 : static void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
     262                 :            : {
     263                 :          0 :         struct wpa_authenticator *wpa_auth = eloop_ctx;
     264                 :          0 :         struct wpa_state_machine *sm = timeout_ctx;
     265                 :            : 
     266                 :          0 :         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK");
     267                 :          0 :         wpa_request_new_ptk(sm);
     268                 :          0 :         wpa_sm_step(sm);
     269                 :          0 : }
     270                 :            : 
     271                 :            : 
     272                 :         58 : static int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx)
     273                 :            : {
     274         [ -  + ]:         58 :         if (sm->pmksa == ctx)
     275                 :          0 :                 sm->pmksa = NULL;
     276                 :         58 :         return 0;
     277                 :            : }
     278                 :            : 
     279                 :            : 
     280                 :         58 : static void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
     281                 :            :                                    void *ctx)
     282                 :            : {
     283                 :         58 :         struct wpa_authenticator *wpa_auth = ctx;
     284                 :         58 :         wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry);
     285                 :         58 : }
     286                 :            : 
     287                 :            : 
     288                 :        635 : static int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth,
     289                 :            :                                           struct wpa_group *group)
     290                 :            : {
     291                 :            :         u8 buf[ETH_ALEN + 8 + sizeof(unsigned long)];
     292                 :            :         u8 rkey[32];
     293                 :            :         unsigned long ptr;
     294                 :            : 
     295         [ -  + ]:        635 :         if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0)
     296                 :          0 :                 return -1;
     297                 :        635 :         wpa_hexdump_key(MSG_DEBUG, "GMK", group->GMK, WPA_GMK_LEN);
     298                 :            : 
     299                 :            :         /*
     300                 :            :          * Counter = PRF-256(Random number, "Init Counter",
     301                 :            :          *                   Local MAC Address || Time)
     302                 :            :          */
     303                 :        635 :         os_memcpy(buf, wpa_auth->addr, ETH_ALEN);
     304                 :        635 :         wpa_get_ntp_timestamp(buf + ETH_ALEN);
     305                 :        635 :         ptr = (unsigned long) group;
     306                 :        635 :         os_memcpy(buf + ETH_ALEN + 8, &ptr, sizeof(ptr));
     307         [ -  + ]:        635 :         if (random_get_bytes(rkey, sizeof(rkey)) < 0)
     308                 :          0 :                 return -1;
     309                 :            : 
     310         [ -  + ]:        635 :         if (sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf),
     311                 :        635 :                      group->Counter, WPA_NONCE_LEN) < 0)
     312                 :          0 :                 return -1;
     313                 :        635 :         wpa_hexdump_key(MSG_DEBUG, "Key Counter",
     314                 :        635 :                         group->Counter, WPA_NONCE_LEN);
     315                 :            : 
     316                 :        635 :         return 0;
     317                 :            : }
     318                 :            : 
     319                 :            : 
     320                 :        350 : static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
     321                 :            :                                          int vlan_id, int delay_init)
     322                 :            : {
     323                 :            :         struct wpa_group *group;
     324                 :            : 
     325                 :        350 :         group = os_zalloc(sizeof(struct wpa_group));
     326         [ -  + ]:        350 :         if (group == NULL)
     327                 :          0 :                 return NULL;
     328                 :            : 
     329                 :        350 :         group->GTKAuthenticator = TRUE;
     330                 :        350 :         group->vlan_id = vlan_id;
     331                 :        350 :         group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group);
     332                 :            : 
     333                 :            :         if (random_pool_ready() != 1) {
     334                 :            :                 wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
     335                 :            :                            "for secure operations - update keys later when "
     336                 :            :                            "the first station connects");
     337                 :            :         }
     338                 :            : 
     339                 :            :         /*
     340                 :            :          * Set initial GMK/Counter value here. The actual values that will be
     341                 :            :          * used in negotiations will be set once the first station tries to
     342                 :            :          * connect. This allows more time for collecting additional randomness
     343                 :            :          * on embedded devices.
     344                 :            :          */
     345         [ -  + ]:        350 :         if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0) {
     346                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
     347                 :            :                            "initialization.");
     348                 :          0 :                 os_free(group);
     349                 :          0 :                 return NULL;
     350                 :            :         }
     351                 :            : 
     352                 :        350 :         group->GInit = TRUE;
     353         [ +  - ]:        350 :         if (delay_init) {
     354                 :        350 :                 wpa_printf(MSG_DEBUG, "WPA: Delay group state machine start "
     355                 :            :                            "until Beacon frames have been configured");
     356                 :            :                 /* Initialization is completed in wpa_init_keys(). */
     357                 :            :         } else {
     358                 :          0 :                 wpa_group_sm_step(wpa_auth, group);
     359                 :          0 :                 group->GInit = FALSE;
     360                 :          0 :                 wpa_group_sm_step(wpa_auth, group);
     361                 :            :         }
     362                 :            : 
     363                 :        350 :         return group;
     364                 :            : }
     365                 :            : 
     366                 :            : 
     367                 :            : /**
     368                 :            :  * wpa_init - Initialize WPA authenticator
     369                 :            :  * @addr: Authenticator address
     370                 :            :  * @conf: Configuration for WPA authenticator
     371                 :            :  * @cb: Callback functions for WPA authenticator
     372                 :            :  * Returns: Pointer to WPA authenticator data or %NULL on failure
     373                 :            :  */
     374                 :        350 : struct wpa_authenticator * wpa_init(const u8 *addr,
     375                 :            :                                     struct wpa_auth_config *conf,
     376                 :            :                                     struct wpa_auth_callbacks *cb)
     377                 :            : {
     378                 :            :         struct wpa_authenticator *wpa_auth;
     379                 :            : 
     380                 :        350 :         wpa_auth = os_zalloc(sizeof(struct wpa_authenticator));
     381         [ -  + ]:        350 :         if (wpa_auth == NULL)
     382                 :          0 :                 return NULL;
     383                 :        350 :         os_memcpy(wpa_auth->addr, addr, ETH_ALEN);
     384                 :        350 :         os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
     385                 :        350 :         os_memcpy(&wpa_auth->cb, cb, sizeof(*cb));
     386                 :            : 
     387         [ -  + ]:        350 :         if (wpa_auth_gen_wpa_ie(wpa_auth)) {
     388                 :          0 :                 wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
     389                 :          0 :                 os_free(wpa_auth);
     390                 :          0 :                 return NULL;
     391                 :            :         }
     392                 :            : 
     393                 :        350 :         wpa_auth->group = wpa_group_init(wpa_auth, 0, 1);
     394         [ -  + ]:        350 :         if (wpa_auth->group == NULL) {
     395                 :          0 :                 os_free(wpa_auth->wpa_ie);
     396                 :          0 :                 os_free(wpa_auth);
     397                 :          0 :                 return NULL;
     398                 :            :         }
     399                 :            : 
     400                 :        350 :         wpa_auth->pmksa = pmksa_cache_auth_init(wpa_auth_pmksa_free_cb,
     401                 :            :                                                 wpa_auth);
     402         [ -  + ]:        350 :         if (wpa_auth->pmksa == NULL) {
     403                 :          0 :                 wpa_printf(MSG_ERROR, "PMKSA cache initialization failed.");
     404                 :          0 :                 os_free(wpa_auth->wpa_ie);
     405                 :          0 :                 os_free(wpa_auth);
     406                 :          0 :                 return NULL;
     407                 :            :         }
     408                 :            : 
     409                 :            : #ifdef CONFIG_IEEE80211R
     410                 :        350 :         wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init();
     411         [ -  + ]:        350 :         if (wpa_auth->ft_pmk_cache == NULL) {
     412                 :          0 :                 wpa_printf(MSG_ERROR, "FT PMK cache initialization failed.");
     413                 :          0 :                 os_free(wpa_auth->wpa_ie);
     414                 :          0 :                 pmksa_cache_auth_deinit(wpa_auth->pmksa);
     415                 :          0 :                 os_free(wpa_auth);
     416                 :          0 :                 return NULL;
     417                 :            :         }
     418                 :            : #endif /* CONFIG_IEEE80211R */
     419                 :            : 
     420         [ +  + ]:        350 :         if (wpa_auth->conf.wpa_gmk_rekey) {
     421                 :        348 :                 eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,
     422                 :            :                                        wpa_rekey_gmk, wpa_auth, NULL);
     423                 :            :         }
     424                 :            : 
     425         [ +  - ]:        350 :         if (wpa_auth->conf.wpa_group_rekey) {
     426                 :        350 :                 eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0,
     427                 :            :                                        wpa_rekey_gtk, wpa_auth, NULL);
     428                 :            :         }
     429                 :            : 
     430                 :            : #ifdef CONFIG_P2P
     431         [ +  + ]:         84 :         if (WPA_GET_BE32(conf->ip_addr_start)) {
     432                 :         46 :                 int count = WPA_GET_BE32(conf->ip_addr_end) -
     433                 :         46 :                         WPA_GET_BE32(conf->ip_addr_start) + 1;
     434         [ -  + ]:         46 :                 if (count > 1000)
     435                 :          0 :                         count = 1000;
     436         [ +  - ]:         46 :                 if (count > 0)
     437                 :         46 :                         wpa_auth->ip_pool = bitfield_alloc(count);
     438                 :            :         }
     439                 :            : #endif /* CONFIG_P2P */
     440                 :            : 
     441                 :        350 :         return wpa_auth;
     442                 :            : }
     443                 :            : 
     444                 :            : 
     445                 :        350 : int wpa_init_keys(struct wpa_authenticator *wpa_auth)
     446                 :            : {
     447                 :        350 :         struct wpa_group *group = wpa_auth->group;
     448                 :            : 
     449                 :        350 :         wpa_printf(MSG_DEBUG, "WPA: Start group state machine to set initial "
     450                 :            :                    "keys");
     451                 :        350 :         wpa_group_sm_step(wpa_auth, group);
     452                 :        350 :         group->GInit = FALSE;
     453                 :        350 :         wpa_group_sm_step(wpa_auth, group);
     454         [ -  + ]:        350 :         if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
     455                 :          0 :                 return -1;
     456                 :        350 :         return 0;
     457                 :            : }
     458                 :            : 
     459                 :            : 
     460                 :            : /**
     461                 :            :  * wpa_deinit - Deinitialize WPA authenticator
     462                 :            :  * @wpa_auth: Pointer to WPA authenticator data from wpa_init()
     463                 :            :  */
     464                 :        350 : void wpa_deinit(struct wpa_authenticator *wpa_auth)
     465                 :            : {
     466                 :            :         struct wpa_group *group, *prev;
     467                 :            : 
     468                 :        350 :         eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL);
     469                 :        350 :         eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
     470                 :            : 
     471                 :            : #ifdef CONFIG_PEERKEY
     472         [ -  + ]:        350 :         while (wpa_auth->stsl_negotiations)
     473                 :          0 :                 wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations);
     474                 :            : #endif /* CONFIG_PEERKEY */
     475                 :            : 
     476                 :        350 :         pmksa_cache_auth_deinit(wpa_auth->pmksa);
     477                 :            : 
     478                 :            : #ifdef CONFIG_IEEE80211R
     479                 :        350 :         wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache);
     480                 :        350 :         wpa_auth->ft_pmk_cache = NULL;
     481                 :            : #endif /* CONFIG_IEEE80211R */
     482                 :            : 
     483                 :            : #ifdef CONFIG_P2P
     484                 :         84 :         bitfield_free(wpa_auth->ip_pool);
     485                 :            : #endif /* CONFIG_P2P */
     486                 :            : 
     487                 :            : 
     488                 :        350 :         os_free(wpa_auth->wpa_ie);
     489                 :            : 
     490                 :        350 :         group = wpa_auth->group;
     491         [ +  + ]:        700 :         while (group) {
     492                 :        350 :                 prev = group;
     493                 :        350 :                 group = group->next;
     494                 :        350 :                 os_free(prev);
     495                 :            :         }
     496                 :            : 
     497                 :        350 :         os_free(wpa_auth);
     498                 :        350 : }
     499                 :            : 
     500                 :            : 
     501                 :            : /**
     502                 :            :  * wpa_reconfig - Update WPA authenticator configuration
     503                 :            :  * @wpa_auth: Pointer to WPA authenticator data from wpa_init()
     504                 :            :  * @conf: Configuration for WPA authenticator
     505                 :            :  */
     506                 :          2 : int wpa_reconfig(struct wpa_authenticator *wpa_auth,
     507                 :            :                  struct wpa_auth_config *conf)
     508                 :            : {
     509                 :            :         struct wpa_group *group;
     510         [ -  + ]:          2 :         if (wpa_auth == NULL)
     511                 :          0 :                 return 0;
     512                 :            : 
     513                 :          2 :         os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
     514         [ -  + ]:          2 :         if (wpa_auth_gen_wpa_ie(wpa_auth)) {
     515                 :          0 :                 wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
     516                 :          0 :                 return -1;
     517                 :            :         }
     518                 :            : 
     519                 :            :         /*
     520                 :            :          * Reinitialize GTK to make sure it is suitable for the new
     521                 :            :          * configuration.
     522                 :            :          */
     523                 :          2 :         group = wpa_auth->group;
     524                 :          2 :         group->GTK_len = wpa_cipher_key_len(wpa_auth->conf.wpa_group);
     525                 :          2 :         group->GInit = TRUE;
     526                 :          2 :         wpa_group_sm_step(wpa_auth, group);
     527                 :          2 :         group->GInit = FALSE;
     528                 :          2 :         wpa_group_sm_step(wpa_auth, group);
     529                 :            : 
     530                 :          2 :         return 0;
     531                 :            : }
     532                 :            : 
     533                 :            : 
     534                 :            : struct wpa_state_machine *
     535                 :        406 : wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
     536                 :            :                   const u8 *p2p_dev_addr)
     537                 :            : {
     538                 :            :         struct wpa_state_machine *sm;
     539                 :            : 
     540         [ -  + ]:        406 :         if (wpa_auth->group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
     541                 :          0 :                 return NULL;
     542                 :            : 
     543                 :        406 :         sm = os_zalloc(sizeof(struct wpa_state_machine));
     544         [ -  + ]:        406 :         if (sm == NULL)
     545                 :          0 :                 return NULL;
     546                 :        406 :         os_memcpy(sm->addr, addr, ETH_ALEN);
     547         [ +  + ]:        406 :         if (p2p_dev_addr)
     548                 :         87 :                 os_memcpy(sm->p2p_dev_addr, p2p_dev_addr, ETH_ALEN);
     549                 :            : 
     550                 :        406 :         sm->wpa_auth = wpa_auth;
     551                 :        406 :         sm->group = wpa_auth->group;
     552                 :            : 
     553                 :        406 :         return sm;
     554                 :            : }
     555                 :            : 
     556                 :            : 
     557                 :        676 : int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
     558                 :            :                             struct wpa_state_machine *sm)
     559                 :            : {
     560 [ +  + ][ +  - ]:        676 :         if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
                 [ +  + ]
     561                 :        246 :                 return -1;
     562                 :            : 
     563                 :            : #ifdef CONFIG_IEEE80211R
     564         [ +  + ]:        430 :         if (sm->ft_completed) {
     565                 :         16 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
     566                 :            :                                 "FT authentication already completed - do not "
     567                 :            :                                 "start 4-way handshake");
     568                 :         16 :                 return 0;
     569                 :            :         }
     570                 :            : #endif /* CONFIG_IEEE80211R */
     571                 :            : 
     572         [ +  + ]:        414 :         if (sm->started) {
     573                 :         16 :                 os_memset(&sm->key_replay, 0, sizeof(sm->key_replay));
     574                 :         16 :                 sm->ReAuthenticationRequest = TRUE;
     575                 :         16 :                 return wpa_sm_step(sm);
     576                 :            :         }
     577                 :            : 
     578                 :        398 :         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
     579                 :            :                         "start authentication");
     580                 :        398 :         sm->started = 1;
     581                 :            : 
     582                 :        398 :         sm->Init = TRUE;
     583         [ -  + ]:        398 :         if (wpa_sm_step(sm) == 1)
     584                 :          0 :                 return 1; /* should not really happen */
     585                 :        398 :         sm->Init = FALSE;
     586                 :        398 :         sm->AuthenticationRequest = TRUE;
     587                 :        676 :         return wpa_sm_step(sm);
     588                 :            : }
     589                 :            : 
     590                 :            : 
     591                 :        247 : void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm)
     592                 :            : {
     593                 :            :         /* WPA/RSN was not used - clear WPA state. This is needed if the STA
     594                 :            :          * reassociates back to the same AP while the previous entry for the
     595                 :            :          * STA has not yet been removed. */
     596         [ +  + ]:        247 :         if (sm == NULL)
     597                 :        247 :                 return;
     598                 :            : 
     599                 :          1 :         sm->wpa_key_mgmt = 0;
     600                 :            : }
     601                 :            : 
     602                 :            : 
     603                 :        406 : static void wpa_free_sta_sm(struct wpa_state_machine *sm)
     604                 :            : {
     605                 :            : #ifdef CONFIG_P2P
     606         [ +  + ]:         98 :         if (WPA_GET_BE32(sm->ip_addr)) {
     607                 :            :                 u32 start;
     608                 :         52 :                 wpa_printf(MSG_DEBUG, "P2P: Free assigned IP "
     609                 :            :                            "address %u.%u.%u.%u from " MACSTR,
     610                 :        104 :                            sm->ip_addr[0], sm->ip_addr[1],
     611                 :        104 :                            sm->ip_addr[2], sm->ip_addr[3],
     612                 :        312 :                            MAC2STR(sm->addr));
     613                 :         52 :                 start = WPA_GET_BE32(sm->wpa_auth->conf.ip_addr_start);
     614                 :         52 :                 bitfield_clear(sm->wpa_auth->ip_pool,
     615                 :         52 :                                WPA_GET_BE32(sm->ip_addr) - start);
     616                 :            :         }
     617                 :            : #endif /* CONFIG_P2P */
     618         [ -  + ]:        406 :         if (sm->GUpdateStationKeys) {
     619                 :          0 :                 sm->group->GKeyDoneStations--;
     620                 :          0 :                 sm->GUpdateStationKeys = FALSE;
     621                 :            :         }
     622                 :            : #ifdef CONFIG_IEEE80211R
     623                 :        406 :         os_free(sm->assoc_resp_ftie);
     624                 :            : #endif /* CONFIG_IEEE80211R */
     625                 :        406 :         os_free(sm->last_rx_eapol_key);
     626                 :        406 :         os_free(sm->wpa_ie);
     627                 :        406 :         os_free(sm);
     628                 :        406 : }
     629                 :            : 
     630                 :            : 
     631                 :        652 : void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
     632                 :            : {
     633         [ +  + ]:        652 :         if (sm == NULL)
     634                 :        652 :                 return;
     635                 :            : 
     636 [ -  + ][ #  # ]:        406 :         if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) {
     637                 :          0 :                 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
     638                 :            :                                 "strict rekeying - force GTK rekey since STA "
     639                 :            :                                 "is leaving");
     640                 :          0 :                 eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL);
     641                 :          0 :                 eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth,
     642                 :            :                                        NULL);
     643                 :            :         }
     644                 :            : 
     645                 :        406 :         eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
     646                 :        406 :         sm->pending_1_of_4_timeout = 0;
     647                 :        406 :         eloop_cancel_timeout(wpa_sm_call_step, sm, NULL);
     648                 :        406 :         eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
     649         [ -  + ]:        406 :         if (sm->in_step_loop) {
     650                 :            :                 /* Must not free state machine while wpa_sm_step() is running.
     651                 :            :                  * Freeing will be completed in the end of wpa_sm_step(). */
     652                 :          0 :                 wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state "
     653                 :          0 :                            "machine deinit for " MACSTR, MAC2STR(sm->addr));
     654                 :          0 :                 sm->pending_deinit = 1;
     655                 :            :         } else
     656                 :        406 :                 wpa_free_sta_sm(sm);
     657                 :            : }
     658                 :            : 
     659                 :            : 
     660                 :          0 : static void wpa_request_new_ptk(struct wpa_state_machine *sm)
     661                 :            : {
     662         [ #  # ]:          0 :         if (sm == NULL)
     663                 :          0 :                 return;
     664                 :            : 
     665                 :          0 :         sm->PTKRequest = TRUE;
     666                 :          0 :         sm->PTK_valid = 0;
     667                 :            : }
     668                 :            : 
     669                 :            : 
     670                 :        846 : static int wpa_replay_counter_valid(struct wpa_key_replay_counter *ctr,
     671                 :            :                                     const u8 *replay_counter)
     672                 :            : {
     673                 :            :         int i;
     674         [ +  - ]:        846 :         for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
     675         [ -  + ]:        846 :                 if (!ctr[i].valid)
     676                 :          0 :                         break;
     677         [ +  - ]:        846 :                 if (os_memcmp(replay_counter, ctr[i].counter,
     678                 :            :                               WPA_REPLAY_COUNTER_LEN) == 0)
     679                 :        846 :                         return 1;
     680                 :            :         }
     681                 :        846 :         return 0;
     682                 :            : }
     683                 :            : 
     684                 :            : 
     685                 :       1692 : static void wpa_replay_counter_mark_invalid(struct wpa_key_replay_counter *ctr,
     686                 :            :                                             const u8 *replay_counter)
     687                 :            : {
     688                 :            :         int i;
     689         [ +  + ]:       8460 :         for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
     690 [ +  + ][ +  - ]:       6768 :                 if (ctr[i].valid &&
     691         [ +  - ]:        846 :                     (replay_counter == NULL ||
     692                 :        846 :                      os_memcmp(replay_counter, ctr[i].counter,
     693                 :            :                                WPA_REPLAY_COUNTER_LEN) == 0))
     694                 :        846 :                         ctr[i].valid = FALSE;
     695                 :            :         }
     696                 :       1692 : }
     697                 :            : 
     698                 :            : 
     699                 :            : #ifdef CONFIG_IEEE80211R
     700                 :          8 : static int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth,
     701                 :            :                                struct wpa_state_machine *sm,
     702                 :            :                                struct wpa_eapol_ie_parse *kde)
     703                 :            : {
     704                 :            :         struct wpa_ie_data ie;
     705                 :            :         struct rsn_mdie *mdie;
     706                 :            : 
     707 [ +  - ][ +  - ]:          8 :         if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 ||
     708         [ -  + ]:          8 :             ie.num_pmkid != 1 || ie.pmkid == NULL) {
     709                 :          0 :                 wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in "
     710                 :            :                            "FT 4-way handshake message 2/4");
     711                 :          0 :                 return -1;
     712                 :            :         }
     713                 :            : 
     714                 :          8 :         os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN);
     715                 :          8 :         wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant",
     716                 :          8 :                     sm->sup_pmk_r1_name, PMKID_LEN);
     717                 :            : 
     718 [ -  + ][ +  - ]:          8 :         if (!kde->mdie || !kde->ftie) {
     719         [ #  # ]:          0 :                 wpa_printf(MSG_DEBUG, "FT: No %s in FT 4-way handshake "
     720                 :          0 :                            "message 2/4", kde->mdie ? "FTIE" : "MDIE");
     721                 :          0 :                 return -1;
     722                 :            :         }
     723                 :            : 
     724                 :          8 :         mdie = (struct rsn_mdie *) (kde->mdie + 2);
     725 [ +  - ][ -  + ]:          8 :         if (kde->mdie[1] < sizeof(struct rsn_mdie) ||
     726                 :          8 :             os_memcmp(wpa_auth->conf.mobility_domain, mdie->mobility_domain,
     727                 :            :                       MOBILITY_DOMAIN_ID_LEN) != 0) {
     728                 :          0 :                 wpa_printf(MSG_DEBUG, "FT: MDIE mismatch");
     729                 :          0 :                 return -1;
     730                 :            :         }
     731                 :            : 
     732 [ +  - ][ +  - ]:          8 :         if (sm->assoc_resp_ftie &&
     733         [ -  + ]:          8 :             (kde->ftie[1] != sm->assoc_resp_ftie[1] ||
     734                 :          8 :              os_memcmp(kde->ftie, sm->assoc_resp_ftie,
     735                 :            :                        2 + sm->assoc_resp_ftie[1]) != 0)) {
     736                 :          0 :                 wpa_printf(MSG_DEBUG, "FT: FTIE mismatch");
     737                 :          0 :                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 2/4",
     738                 :          0 :                             kde->ftie, kde->ftie_len);
     739                 :          0 :                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)AssocResp",
     740                 :          0 :                             sm->assoc_resp_ftie, 2 + sm->assoc_resp_ftie[1]);
     741                 :          0 :                 return -1;
     742                 :            :         }
     743                 :            : 
     744                 :          8 :         return 0;
     745                 :            : }
     746                 :            : #endif /* CONFIG_IEEE80211R */
     747                 :            : 
     748                 :            : 
     749                 :          0 : static int wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
     750                 :            :                                     struct wpa_state_machine *sm, int group)
     751                 :            : {
     752                 :            :         /* Supplicant reported a Michael MIC error */
     753                 :          0 :         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
     754                 :            :                          "received EAPOL-Key Error Request "
     755                 :            :                          "(STA detected Michael MIC failure (group=%d))",
     756                 :            :                          group);
     757                 :            : 
     758 [ #  # ][ #  # ]:          0 :         if (group && wpa_auth->conf.wpa_group != WPA_CIPHER_TKIP) {
     759                 :          0 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
     760                 :            :                                 "ignore Michael MIC failure report since "
     761                 :            :                                 "group cipher is not TKIP");
     762 [ #  # ][ #  # ]:          0 :         } else if (!group && sm->pairwise != WPA_CIPHER_TKIP) {
     763                 :          0 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
     764                 :            :                                 "ignore Michael MIC failure report since "
     765                 :            :                                 "pairwise cipher is not TKIP");
     766                 :            :         } else {
     767         [ #  # ]:          0 :                 if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0)
     768                 :          0 :                         return 1; /* STA entry was removed */
     769                 :          0 :                 sm->dot11RSNAStatsTKIPRemoteMICFailures++;
     770                 :          0 :                 wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
     771                 :            :         }
     772                 :            : 
     773                 :            :         /*
     774                 :            :          * Error report is not a request for a new key handshake, but since
     775                 :            :          * Authenticator may do it, let's change the keys now anyway.
     776                 :            :          */
     777                 :          0 :         wpa_request_new_ptk(sm);
     778                 :          0 :         return 0;
     779                 :            : }
     780                 :            : 
     781                 :            : 
     782                 :        847 : void wpa_receive(struct wpa_authenticator *wpa_auth,
     783                 :            :                  struct wpa_state_machine *sm,
     784                 :            :                  u8 *data, size_t data_len)
     785                 :            : {
     786                 :            :         struct ieee802_1x_hdr *hdr;
     787                 :            :         struct wpa_eapol_key *key;
     788                 :            :         u16 key_info, key_data_length;
     789                 :            :         enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST,
     790                 :            :                SMK_M1, SMK_M3, SMK_ERROR } msg;
     791                 :            :         char *msgtxt;
     792                 :            :         struct wpa_eapol_ie_parse kde;
     793                 :            :         int ft;
     794                 :            :         const u8 *eapol_key_ie;
     795                 :            :         size_t eapol_key_ie_len;
     796                 :            : 
     797 [ +  - ][ +  - ]:        847 :         if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
                 [ -  + ]
     798                 :          0 :                 return;
     799                 :            : 
     800         [ -  + ]:        847 :         if (data_len < sizeof(*hdr) + sizeof(*key))
     801                 :          0 :                 return;
     802                 :            : 
     803                 :        847 :         hdr = (struct ieee802_1x_hdr *) data;
     804                 :        847 :         key = (struct wpa_eapol_key *) (hdr + 1);
     805                 :        847 :         key_info = WPA_GET_BE16(key->key_info);
     806                 :        847 :         key_data_length = WPA_GET_BE16(key->key_data_length);
     807                 :        847 :         wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
     808                 :            :                    " key_info=0x%x type=%u key_data_length=%u",
     809                 :       5929 :                    MAC2STR(sm->addr), key_info, key->type, key_data_length);
     810         [ -  + ]:        847 :         if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
     811                 :          0 :                 wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
     812                 :            :                            "key_data overflow (%d > %lu)",
     813                 :            :                            key_data_length,
     814                 :            :                            (unsigned long) (data_len - sizeof(*hdr) -
     815                 :            :                                             sizeof(*key)));
     816                 :          0 :                 return;
     817                 :            :         }
     818                 :            : 
     819         [ +  + ]:        847 :         if (sm->wpa == WPA_VERSION_WPA2) {
     820         [ -  + ]:        823 :                 if (key->type == EAPOL_KEY_TYPE_WPA) {
     821                 :            :                         /*
     822                 :            :                          * Some deployed station implementations seem to send
     823                 :            :                          * msg 4/4 with incorrect type value in WPA2 mode.
     824                 :            :                          */
     825                 :          0 :                         wpa_printf(MSG_DEBUG, "Workaround: Allow EAPOL-Key "
     826                 :            :                                    "with unexpected WPA type in RSN mode");
     827         [ -  + ]:        823 :                 } else if (key->type != EAPOL_KEY_TYPE_RSN) {
     828                 :          0 :                         wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
     829                 :            :                                    "unexpected type %d in RSN mode",
     830                 :          0 :                                    key->type);
     831                 :          0 :                         return;
     832                 :            :                 }
     833                 :            :         } else {
     834         [ -  + ]:         24 :                 if (key->type != EAPOL_KEY_TYPE_WPA) {
     835                 :          0 :                         wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
     836                 :            :                                    "unexpected type %d in WPA mode",
     837                 :          0 :                                    key->type);
     838                 :          0 :                         return;
     839                 :            :                 }
     840                 :            :         }
     841                 :            : 
     842                 :        847 :         wpa_hexdump(MSG_DEBUG, "WPA: Received Key Nonce", key->key_nonce,
     843                 :            :                     WPA_NONCE_LEN);
     844                 :        847 :         wpa_hexdump(MSG_DEBUG, "WPA: Received Replay Counter",
     845                 :        847 :                     key->replay_counter, WPA_REPLAY_COUNTER_LEN);
     846                 :            : 
     847                 :            :         /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys
     848                 :            :          * are set */
     849                 :            : 
     850         [ +  + ]:        847 :         if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) ==
     851                 :            :             (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) {
     852         [ -  + ]:          1 :                 if (key_info & WPA_KEY_INFO_ERROR) {
     853                 :          0 :                         msg = SMK_ERROR;
     854                 :          0 :                         msgtxt = "SMK Error";
     855                 :            :                 } else {
     856                 :          1 :                         msg = SMK_M1;
     857                 :          1 :                         msgtxt = "SMK M1";
     858                 :            :                 }
     859         [ +  + ]:        846 :         } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
     860                 :          1 :                 msg = SMK_M3;
     861                 :          1 :                 msgtxt = "SMK M3";
     862         [ -  + ]:        845 :         } else if (key_info & WPA_KEY_INFO_REQUEST) {
     863                 :          0 :                 msg = REQUEST;
     864                 :          0 :                 msgtxt = "Request";
     865         [ +  + ]:        845 :         } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) {
     866                 :          9 :                 msg = GROUP_2;
     867                 :          9 :                 msgtxt = "2/2 Group";
     868         [ +  + ]:        836 :         } else if (key_data_length == 0) {
     869                 :        404 :                 msg = PAIRWISE_4;
     870                 :        404 :                 msgtxt = "4/4 Pairwise";
     871                 :            :         } else {
     872                 :        432 :                 msg = PAIRWISE_2;
     873                 :        432 :                 msgtxt = "2/4 Pairwise";
     874                 :            :         }
     875                 :            : 
     876                 :            :         /* TODO: key_info type validation for PeerKey */
     877 [ +  - ][ +  + ]:        847 :         if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 ||
         [ +  + ][ +  + ]
     878                 :            :             msg == GROUP_2) {
     879                 :        845 :                 u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
     880 [ +  + ][ -  + ]:        845 :                 if (sm->pairwise == WPA_CIPHER_CCMP ||
     881                 :         26 :                     sm->pairwise == WPA_CIPHER_GCMP) {
     882 [ +  + ][ +  + ]:        819 :                         if (wpa_use_aes_cmac(sm) &&
     883         [ -  + ]:         32 :                             sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN &&
     884                 :            :                             ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
     885                 :          0 :                                 wpa_auth_logger(wpa_auth, sm->addr,
     886                 :            :                                                 LOGGER_WARNING,
     887                 :            :                                                 "advertised support for "
     888                 :            :                                                 "AES-128-CMAC, but did not "
     889                 :            :                                                 "use it");
     890                 :          0 :                                 return;
     891                 :            :                         }
     892                 :            : 
     893 [ +  + ][ -  + ]:        819 :                         if (!wpa_use_aes_cmac(sm) &&
     894                 :            :                             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
     895                 :          0 :                                 wpa_auth_logger(wpa_auth, sm->addr,
     896                 :            :                                                 LOGGER_WARNING,
     897                 :            :                                                 "did not use HMAC-SHA1-AES "
     898                 :            :                                                 "with CCMP/GCMP");
     899                 :          0 :                                 return;
     900                 :            :                         }
     901                 :            :                 }
     902                 :            :         }
     903                 :            : 
     904         [ +  + ]:        847 :         if (key_info & WPA_KEY_INFO_REQUEST) {
     905 [ -  + ][ #  # ]:          1 :                 if (sm->req_replay_counter_used &&
     906                 :          0 :                     os_memcmp(key->replay_counter, sm->req_replay_counter,
     907                 :            :                               WPA_REPLAY_COUNTER_LEN) <= 0) {
     908                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING,
     909                 :            :                                         "received EAPOL-Key request with "
     910                 :            :                                         "replayed counter");
     911                 :          0 :                         return;
     912                 :            :                 }
     913                 :            :         }
     914                 :            : 
     915   [ +  +  -  + ]:       1693 :         if (!(key_info & WPA_KEY_INFO_REQUEST) &&
     916                 :        846 :             !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) {
     917                 :            :                 int i;
     918                 :            : 
     919   [ #  #  #  # ]:          0 :                 if (msg == PAIRWISE_2 &&
     920                 :          0 :                     wpa_replay_counter_valid(sm->prev_key_replay,
     921         [ #  # ]:          0 :                                              key->replay_counter) &&
     922         [ #  # ]:          0 :                     sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
     923                 :          0 :                     os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0)
     924                 :            :                 {
     925                 :            :                         /*
     926                 :            :                          * Some supplicant implementations (e.g., Windows XP
     927                 :            :                          * WZC) update SNonce for each EAPOL-Key 2/4. This
     928                 :            :                          * breaks the workaround on accepting any of the
     929                 :            :                          * pending requests, so allow the SNonce to be updated
     930                 :            :                          * even if we have already sent out EAPOL-Key 3/4.
     931                 :            :                          */
     932                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
     933                 :            :                                          "Process SNonce update from STA "
     934                 :            :                                          "based on retransmitted EAPOL-Key "
     935                 :            :                                          "1/4");
     936                 :          0 :                         sm->update_snonce = 1;
     937                 :          0 :                         wpa_replay_counter_mark_invalid(sm->prev_key_replay,
     938                 :          0 :                                                         key->replay_counter);
     939                 :          0 :                         goto continue_processing;
     940                 :            :                 }
     941                 :            : 
     942   [ #  #  #  # ]:          0 :                 if (msg == PAIRWISE_2 &&
     943                 :          0 :                     wpa_replay_counter_valid(sm->prev_key_replay,
     944         [ #  # ]:          0 :                                              key->replay_counter) &&
     945                 :          0 :                     sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) {
     946                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
     947                 :            :                                          "ignore retransmitted EAPOL-Key %s - "
     948                 :            :                                          "SNonce did not change", msgtxt);
     949                 :            :                 } else {
     950                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
     951                 :            :                                          "received EAPOL-Key %s with "
     952                 :            :                                          "unexpected replay counter", msgtxt);
     953                 :            :                 }
     954         [ #  # ]:          0 :                 for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
     955         [ #  # ]:          0 :                         if (!sm->key_replay[i].valid)
     956                 :          0 :                                 break;
     957                 :          0 :                         wpa_hexdump(MSG_DEBUG, "pending replay counter",
     958                 :          0 :                                     sm->key_replay[i].counter,
     959                 :            :                                     WPA_REPLAY_COUNTER_LEN);
     960                 :            :                 }
     961                 :          0 :                 wpa_hexdump(MSG_DEBUG, "received replay counter",
     962                 :          0 :                             key->replay_counter, WPA_REPLAY_COUNTER_LEN);
     963                 :          0 :                 return;
     964                 :            :         }
     965                 :            : 
     966                 :            : continue_processing:
     967   [ +  +  +  +  :        847 :         switch (msg) {
                   -  - ]
     968                 :            :         case PAIRWISE_2:
     969 [ -  + ][ #  # ]:        432 :                 if (sm->wpa_ptk_state != WPA_PTK_PTKSTART &&
     970         [ #  # ]:          0 :                     sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING &&
     971         [ #  # ]:          0 :                     (!sm->update_snonce ||
     972                 :          0 :                      sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING)) {
     973                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
     974                 :            :                                          "received EAPOL-Key msg 2/4 in "
     975                 :            :                                          "invalid state (%d) - dropped",
     976                 :          0 :                                          sm->wpa_ptk_state);
     977                 :          0 :                         return;
     978                 :            :                 }
     979                 :            :                 random_add_randomness(key->key_nonce, WPA_NONCE_LEN);
     980         [ -  + ]:        432 :                 if (sm->group->reject_4way_hs_for_entropy) {
     981                 :            :                         /*
     982                 :            :                          * The system did not have enough entropy to generate
     983                 :            :                          * strong random numbers. Reject the first 4-way
     984                 :            :                          * handshake(s) and collect some entropy based on the
     985                 :            :                          * information from it. Once enough entropy is
     986                 :            :                          * available, the next atempt will trigger GMK/Key
     987                 :            :                          * Counter update and the station will be allowed to
     988                 :            :                          * continue.
     989                 :            :                          */
     990                 :          0 :                         wpa_printf(MSG_DEBUG, "WPA: Reject 4-way handshake to "
     991                 :            :                                    "collect more entropy for random number "
     992                 :            :                                    "generation");
     993                 :            :                         random_mark_pool_ready();
     994                 :          0 :                         wpa_sta_disconnect(wpa_auth, sm->addr);
     995                 :          0 :                         return;
     996                 :            :                 }
     997         [ -  + ]:        432 :                 if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length,
     998                 :            :                                       &kde) < 0) {
     999                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
    1000                 :            :                                          "received EAPOL-Key msg 2/4 with "
    1001                 :            :                                          "invalid Key Data contents");
    1002                 :          0 :                         return;
    1003                 :            :                 }
    1004         [ +  + ]:        432 :                 if (kde.rsn_ie) {
    1005                 :        423 :                         eapol_key_ie = kde.rsn_ie;
    1006                 :        423 :                         eapol_key_ie_len = kde.rsn_ie_len;
    1007         [ +  + ]:          9 :                 } else if (kde.osen) {
    1008                 :          1 :                         eapol_key_ie = kde.osen;
    1009                 :          1 :                         eapol_key_ie_len = kde.osen_len;
    1010                 :            :                 } else {
    1011                 :          8 :                         eapol_key_ie = kde.wpa_ie;
    1012                 :          8 :                         eapol_key_ie_len = kde.wpa_ie_len;
    1013                 :            :                 }
    1014   [ +  +  +  + ]:        856 :                 ft = sm->wpa == WPA_VERSION_WPA2 &&
    1015                 :        424 :                         wpa_key_mgmt_ft(sm->wpa_key_mgmt);
    1016   [ +  -  -  + ]:        864 :                 if (sm->wpa_ie == NULL ||
    1017                 :        432 :                     wpa_compare_rsn_ie(ft,
    1018                 :        432 :                                        sm->wpa_ie, sm->wpa_ie_len,
    1019                 :            :                                        eapol_key_ie, eapol_key_ie_len)) {
    1020                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1021                 :            :                                         "WPA IE from (Re)AssocReq did not "
    1022                 :            :                                         "match with msg 2/4");
    1023         [ #  # ]:          0 :                         if (sm->wpa_ie) {
    1024                 :          0 :                                 wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq",
    1025                 :          0 :                                             sm->wpa_ie, sm->wpa_ie_len);
    1026                 :            :                         }
    1027                 :          0 :                         wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4",
    1028                 :            :                                     eapol_key_ie, eapol_key_ie_len);
    1029                 :            :                         /* MLME-DEAUTHENTICATE.request */
    1030                 :          0 :                         wpa_sta_disconnect(wpa_auth, sm->addr);
    1031                 :          0 :                         return;
    1032                 :            :                 }
    1033                 :            : #ifdef CONFIG_IEEE80211R
    1034 [ +  + ][ -  + ]:        432 :                 if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) {
    1035                 :          0 :                         wpa_sta_disconnect(wpa_auth, sm->addr);
    1036                 :          0 :                         return;
    1037                 :            :                 }
    1038                 :            : #endif /* CONFIG_IEEE80211R */
    1039                 :            : #ifdef CONFIG_P2P
    1040 [ +  + ][ +  - ]:        116 :                 if (kde.ip_addr_req && kde.ip_addr_req[0] &&
                 [ +  + ]
    1041         [ +  + ]:         70 :                     wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) {
    1042                 :            :                         int idx;
    1043                 :         52 :                         wpa_printf(MSG_DEBUG, "P2P: IP address requested in "
    1044                 :            :                                    "EAPOL-Key exchange");
    1045                 :         52 :                         idx = bitfield_get_first_zero(wpa_auth->ip_pool);
    1046         [ +  - ]:         52 :                         if (idx >= 0) {
    1047                 :         52 :                                 u32 start = WPA_GET_BE32(wpa_auth->conf.
    1048                 :            :                                                          ip_addr_start);
    1049                 :         52 :                                 bitfield_set(wpa_auth->ip_pool, idx);
    1050                 :         52 :                                 WPA_PUT_BE32(sm->ip_addr, start + idx);
    1051                 :         52 :                                 wpa_printf(MSG_DEBUG, "P2P: Assigned IP "
    1052                 :            :                                            "address %u.%u.%u.%u to " MACSTR,
    1053                 :        104 :                                            sm->ip_addr[0], sm->ip_addr[1],
    1054                 :        104 :                                            sm->ip_addr[2], sm->ip_addr[3],
    1055                 :        312 :                                            MAC2STR(sm->addr));
    1056                 :            :                         }
    1057                 :            :                 }
    1058                 :            : #endif /* CONFIG_P2P */
    1059                 :        432 :                 break;
    1060                 :            :         case PAIRWISE_4:
    1061 [ +  - ][ -  + ]:        404 :                 if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING ||
    1062                 :        404 :                     !sm->PTK_valid) {
    1063                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
    1064                 :            :                                          "received EAPOL-Key msg 4/4 in "
    1065                 :            :                                          "invalid state (%d) - dropped",
    1066                 :          0 :                                          sm->wpa_ptk_state);
    1067                 :          0 :                         return;
    1068                 :            :                 }
    1069                 :        404 :                 break;
    1070                 :            :         case GROUP_2:
    1071         [ +  - ]:          9 :                 if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING
    1072         [ -  + ]:          9 :                     || !sm->PTK_valid) {
    1073                 :          0 :                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
    1074                 :            :                                          "received EAPOL-Key msg 2/2 in "
    1075                 :            :                                          "invalid state (%d) - dropped",
    1076                 :          0 :                                          sm->wpa_ptk_group_state);
    1077                 :          0 :                         return;
    1078                 :            :                 }
    1079                 :          9 :                 break;
    1080                 :            : #ifdef CONFIG_PEERKEY
    1081                 :            :         case SMK_M1:
    1082                 :            :         case SMK_M3:
    1083                 :            :         case SMK_ERROR:
    1084         [ -  + ]:          2 :                 if (!wpa_auth->conf.peerkey) {
    1085                 :          0 :                         wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but "
    1086                 :            :                                    "PeerKey use disabled - ignoring message");
    1087                 :          0 :                         return;
    1088                 :            :                 }
    1089         [ -  + ]:          2 :                 if (!sm->PTK_valid) {
    1090                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1091                 :            :                                         "received EAPOL-Key msg SMK in "
    1092                 :            :                                         "invalid state - dropped");
    1093                 :          0 :                         return;
    1094                 :            :                 }
    1095                 :          2 :                 break;
    1096                 :            : #else /* CONFIG_PEERKEY */
    1097                 :            :         case SMK_M1:
    1098                 :            :         case SMK_M3:
    1099                 :            :         case SMK_ERROR:
    1100                 :            :                 return; /* STSL disabled - ignore SMK messages */
    1101                 :            : #endif /* CONFIG_PEERKEY */
    1102                 :            :         case REQUEST:
    1103                 :          0 :                 break;
    1104                 :            :         }
    1105                 :            : 
    1106                 :        847 :         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
    1107                 :            :                          "received EAPOL-Key frame (%s)", msgtxt);
    1108                 :            : 
    1109         [ -  + ]:        847 :         if (key_info & WPA_KEY_INFO_ACK) {
    1110                 :          0 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1111                 :            :                                 "received invalid EAPOL-Key: Key Ack set");
    1112                 :          0 :                 return;
    1113                 :            :         }
    1114                 :            : 
    1115         [ -  + ]:        847 :         if (!(key_info & WPA_KEY_INFO_MIC)) {
    1116                 :          0 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1117                 :            :                                 "received invalid EAPOL-Key: Key MIC not set");
    1118                 :          0 :                 return;
    1119                 :            :         }
    1120                 :            : 
    1121                 :        847 :         sm->MICVerified = FALSE;
    1122 [ +  + ][ +  - ]:        847 :         if (sm->PTK_valid && !sm->update_snonce) {
    1123         [ -  + ]:        415 :                 if (wpa_verify_key_mic(&sm->PTK, data, data_len)) {
    1124                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1125                 :            :                                         "received EAPOL-Key with invalid MIC");
    1126                 :          0 :                         return;
    1127                 :            :                 }
    1128                 :        415 :                 sm->MICVerified = TRUE;
    1129                 :        415 :                 eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
    1130                 :        415 :                 sm->pending_1_of_4_timeout = 0;
    1131                 :            :         }
    1132                 :            : 
    1133         [ +  + ]:        847 :         if (key_info & WPA_KEY_INFO_REQUEST) {
    1134         [ +  - ]:          1 :                 if (sm->MICVerified) {
    1135                 :          1 :                         sm->req_replay_counter_used = 1;
    1136                 :          1 :                         os_memcpy(sm->req_replay_counter, key->replay_counter,
    1137                 :            :                                   WPA_REPLAY_COUNTER_LEN);
    1138                 :            :                 } else {
    1139                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1140                 :            :                                         "received EAPOL-Key request with "
    1141                 :            :                                         "invalid MIC");
    1142                 :          0 :                         return;
    1143                 :            :                 }
    1144                 :            : 
    1145                 :            :                 /*
    1146                 :            :                  * TODO: should decrypt key data field if encryption was used;
    1147                 :            :                  * even though MAC address KDE is not normally encrypted,
    1148                 :            :                  * supplicant is allowed to encrypt it.
    1149                 :            :                  */
    1150         [ -  + ]:          1 :                 if (msg == SMK_ERROR) {
    1151                 :            : #ifdef CONFIG_PEERKEY
    1152                 :          0 :                         wpa_smk_error(wpa_auth, sm, key);
    1153                 :            : #endif /* CONFIG_PEERKEY */
    1154                 :          0 :                         return;
    1155         [ -  + ]:          1 :                 } else if (key_info & WPA_KEY_INFO_ERROR) {
    1156         [ #  # ]:          0 :                         if (wpa_receive_error_report(
    1157                 :            :                                     wpa_auth, sm,
    1158                 :          0 :                                     !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0)
    1159                 :          0 :                                 return; /* STA entry was removed */
    1160         [ -  + ]:          1 :                 } else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
    1161                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1162                 :            :                                         "received EAPOL-Key Request for new "
    1163                 :            :                                         "4-Way Handshake");
    1164                 :          0 :                         wpa_request_new_ptk(sm);
    1165                 :            : #ifdef CONFIG_PEERKEY
    1166         [ +  - ]:          1 :                 } else if (msg == SMK_M1) {
    1167                 :          1 :                         wpa_smk_m1(wpa_auth, sm, key);
    1168                 :            : #endif /* CONFIG_PEERKEY */
    1169   [ #  #  #  # ]:          0 :                 } else if (key_data_length > 0 &&
    1170                 :          0 :                            wpa_parse_kde_ies((const u8 *) (key + 1),
    1171         [ #  # ]:          0 :                                              key_data_length, &kde) == 0 &&
    1172                 :          0 :                            kde.mac_addr) {
    1173                 :            :                 } else {
    1174                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1175                 :            :                                         "received EAPOL-Key Request for GTK "
    1176                 :            :                                         "rekeying");
    1177                 :          0 :                         eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
    1178                 :          1 :                         wpa_rekey_gtk(wpa_auth, NULL);
    1179                 :            :                 }
    1180                 :            :         } else {
    1181                 :            :                 /* Do not allow the same key replay counter to be reused. */
    1182                 :        846 :                 wpa_replay_counter_mark_invalid(sm->key_replay,
    1183                 :        846 :                                                 key->replay_counter);
    1184                 :            : 
    1185         [ +  + ]:        846 :                 if (msg == PAIRWISE_2) {
    1186                 :            :                         /*
    1187                 :            :                          * Maintain a copy of the pending EAPOL-Key frames in
    1188                 :            :                          * case the EAPOL-Key frame was retransmitted. This is
    1189                 :            :                          * needed to allow EAPOL-Key msg 2/4 reply to another
    1190                 :            :                          * pending msg 1/4 to update the SNonce to work around
    1191                 :            :                          * unexpected supplicant behavior.
    1192                 :            :                          */
    1193                 :        432 :                         os_memcpy(sm->prev_key_replay, sm->key_replay,
    1194                 :            :                                   sizeof(sm->key_replay));
    1195                 :            :                 } else {
    1196                 :        414 :                         os_memset(sm->prev_key_replay, 0,
    1197                 :            :                                   sizeof(sm->prev_key_replay));
    1198                 :            :                 }
    1199                 :            : 
    1200                 :            :                 /*
    1201                 :            :                  * Make sure old valid counters are not accepted anymore and
    1202                 :            :                  * do not get copied again.
    1203                 :            :                  */
    1204                 :        846 :                 wpa_replay_counter_mark_invalid(sm->key_replay, NULL);
    1205                 :            :         }
    1206                 :            : 
    1207                 :            : #ifdef CONFIG_PEERKEY
    1208         [ +  + ]:        847 :         if (msg == SMK_M3) {
    1209                 :          1 :                 wpa_smk_m3(wpa_auth, sm, key);
    1210                 :          1 :                 return;
    1211                 :            :         }
    1212                 :            : #endif /* CONFIG_PEERKEY */
    1213                 :            : 
    1214                 :        846 :         os_free(sm->last_rx_eapol_key);
    1215                 :        846 :         sm->last_rx_eapol_key = os_malloc(data_len);
    1216         [ -  + ]:        846 :         if (sm->last_rx_eapol_key == NULL)
    1217                 :          0 :                 return;
    1218                 :        846 :         os_memcpy(sm->last_rx_eapol_key, data, data_len);
    1219                 :        846 :         sm->last_rx_eapol_key_len = data_len;
    1220                 :            : 
    1221                 :        846 :         sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE);
    1222                 :        846 :         sm->EAPOLKeyReceived = TRUE;
    1223                 :        846 :         sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
    1224                 :        846 :         sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
    1225                 :        846 :         os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN);
    1226                 :        847 :         wpa_sm_step(sm);
    1227                 :            : }
    1228                 :            : 
    1229                 :            : 
    1230                 :        810 : static int wpa_gmk_to_gtk(const u8 *gmk, const char *label, const u8 *addr,
    1231                 :            :                           const u8 *gnonce, u8 *gtk, size_t gtk_len)
    1232                 :            : {
    1233                 :            :         u8 data[ETH_ALEN + WPA_NONCE_LEN + 8 + 16];
    1234                 :            :         u8 *pos;
    1235                 :        810 :         int ret = 0;
    1236                 :            : 
    1237                 :            :         /* GTK = PRF-X(GMK, "Group key expansion",
    1238                 :            :          *      AA || GNonce || Time || random data)
    1239                 :            :          * The example described in the IEEE 802.11 standard uses only AA and
    1240                 :            :          * GNonce as inputs here. Add some more entropy since this derivation
    1241                 :            :          * is done only at the Authenticator and as such, does not need to be
    1242                 :            :          * exactly same.
    1243                 :            :          */
    1244                 :        810 :         os_memcpy(data, addr, ETH_ALEN);
    1245                 :        810 :         os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN);
    1246                 :        810 :         pos = data + ETH_ALEN + WPA_NONCE_LEN;
    1247                 :        810 :         wpa_get_ntp_timestamp(pos);
    1248                 :        810 :         pos += 8;
    1249         [ -  + ]:        810 :         if (random_get_bytes(pos, 16) < 0)
    1250                 :          0 :                 ret = -1;
    1251                 :            : 
    1252                 :            : #ifdef CONFIG_IEEE80211W
    1253                 :        810 :         sha256_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len);
    1254                 :            : #else /* CONFIG_IEEE80211W */
    1255                 :            :         if (sha1_prf(gmk, WPA_GMK_LEN, label, data, sizeof(data), gtk, gtk_len)
    1256                 :            :             < 0)
    1257                 :            :                 ret = -1;
    1258                 :            : #endif /* CONFIG_IEEE80211W */
    1259                 :            : 
    1260                 :        810 :         return ret;
    1261                 :            : }
    1262                 :            : 
    1263                 :            : 
    1264                 :         28 : static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx)
    1265                 :            : {
    1266                 :         28 :         struct wpa_authenticator *wpa_auth = eloop_ctx;
    1267                 :         28 :         struct wpa_state_machine *sm = timeout_ctx;
    1268                 :            : 
    1269                 :         28 :         sm->pending_1_of_4_timeout = 0;
    1270                 :         28 :         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout");
    1271                 :         28 :         sm->TimeoutEvt = TRUE;
    1272                 :         28 :         wpa_sm_step(sm);
    1273                 :         28 : }
    1274                 :            : 
    1275                 :            : 
    1276                 :        848 : void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
    1277                 :            :                       struct wpa_state_machine *sm, int key_info,
    1278                 :            :                       const u8 *key_rsc, const u8 *nonce,
    1279                 :            :                       const u8 *kde, size_t kde_len,
    1280                 :            :                       int keyidx, int encr, int force_version)
    1281                 :            : {
    1282                 :            :         struct ieee802_1x_hdr *hdr;
    1283                 :            :         struct wpa_eapol_key *key;
    1284                 :            :         size_t len;
    1285                 :            :         int alg;
    1286                 :        848 :         int key_data_len, pad_len = 0;
    1287                 :            :         u8 *buf, *pos;
    1288                 :            :         int version, pairwise;
    1289                 :            :         int i;
    1290                 :            : 
    1291                 :        848 :         len = sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key);
    1292                 :            : 
    1293         [ -  + ]:        848 :         if (force_version)
    1294                 :          0 :                 version = force_version;
    1295         [ +  + ]:        848 :         else if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN)
    1296                 :          2 :                 version = WPA_KEY_INFO_TYPE_AKM_DEFINED;
    1297         [ +  + ]:        846 :         else if (wpa_use_aes_cmac(sm))
    1298                 :         32 :                 version = WPA_KEY_INFO_TYPE_AES_128_CMAC;
    1299         [ +  + ]:        814 :         else if (sm->pairwise != WPA_CIPHER_TKIP)
    1300                 :        788 :                 version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
    1301                 :            :         else
    1302                 :         26 :                 version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
    1303                 :            : 
    1304                 :        848 :         pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
    1305                 :            : 
    1306                 :        848 :         wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d "
    1307                 :            :                    "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d "
    1308                 :            :                    "encr=%d)",
    1309                 :            :                    version,
    1310                 :        848 :                    (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0,
    1311                 :        848 :                    (key_info & WPA_KEY_INFO_MIC) ? 1 : 0,
    1312                 :        848 :                    (key_info & WPA_KEY_INFO_ACK) ? 1 : 0,
    1313                 :        848 :                    (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0,
    1314                 :            :                    pairwise, (unsigned long) kde_len, keyidx, encr);
    1315                 :            : 
    1316                 :        848 :         key_data_len = kde_len;
    1317                 :            : 
    1318 [ +  + ][ +  + ]:        848 :         if ((version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
    1319         [ +  + ]:         58 :              sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
    1320         [ +  + ]:        822 :              version == WPA_KEY_INFO_TYPE_AES_128_CMAC) && encr) {
    1321                 :        398 :                 pad_len = key_data_len % 8;
    1322         [ +  + ]:        398 :                 if (pad_len)
    1323                 :        346 :                         pad_len = 8 - pad_len;
    1324                 :        398 :                 key_data_len += pad_len + 8;
    1325                 :            :         }
    1326                 :            : 
    1327                 :        848 :         len += key_data_len;
    1328                 :            : 
    1329                 :        848 :         hdr = os_zalloc(len);
    1330         [ -  + ]:        848 :         if (hdr == NULL)
    1331                 :          0 :                 return;
    1332                 :        848 :         hdr->version = wpa_auth->conf.eapol_version;
    1333                 :        848 :         hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
    1334                 :        848 :         hdr->length = host_to_be16(len  - sizeof(*hdr));
    1335                 :        848 :         key = (struct wpa_eapol_key *) (hdr + 1);
    1336                 :            : 
    1337         [ +  + ]:        848 :         key->type = sm->wpa == WPA_VERSION_WPA2 ?
    1338                 :            :                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
    1339                 :        848 :         key_info |= version;
    1340 [ +  + ][ +  + ]:        848 :         if (encr && sm->wpa == WPA_VERSION_WPA2)
    1341                 :        399 :                 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
    1342         [ +  + ]:        848 :         if (sm->wpa != WPA_VERSION_WPA2)
    1343                 :         24 :                 key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT;
    1344                 :        848 :         WPA_PUT_BE16(key->key_info, key_info);
    1345                 :            : 
    1346         [ +  + ]:        848 :         alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group;
    1347                 :        848 :         WPA_PUT_BE16(key->key_length, wpa_cipher_key_len(alg));
    1348         [ +  + ]:        848 :         if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
    1349                 :          3 :                 WPA_PUT_BE16(key->key_length, 0);
    1350                 :            : 
    1351                 :            :         /* FIX: STSL: what to use as key_replay_counter? */
    1352         [ +  + ]:       3392 :         for (i = RSNA_MAX_EAPOL_RETRIES - 1; i > 0; i--) {
    1353                 :       2544 :                 sm->key_replay[i].valid = sm->key_replay[i - 1].valid;
    1354                 :       2544 :                 os_memcpy(sm->key_replay[i].counter,
    1355                 :            :                           sm->key_replay[i - 1].counter,
    1356                 :            :                           WPA_REPLAY_COUNTER_LEN);
    1357                 :            :         }
    1358                 :        848 :         inc_byte_array(sm->key_replay[0].counter, WPA_REPLAY_COUNTER_LEN);
    1359                 :        848 :         os_memcpy(key->replay_counter, sm->key_replay[0].counter,
    1360                 :            :                   WPA_REPLAY_COUNTER_LEN);
    1361                 :        848 :         sm->key_replay[0].valid = TRUE;
    1362                 :            : 
    1363         [ +  - ]:        848 :         if (nonce)
    1364                 :        848 :                 os_memcpy(key->key_nonce, nonce, WPA_NONCE_LEN);
    1365                 :            : 
    1366         [ +  + ]:        848 :         if (key_rsc)
    1367                 :        405 :                 os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN);
    1368                 :            : 
    1369 [ +  + ][ +  + ]:        848 :         if (kde && !encr) {
    1370                 :        186 :                 os_memcpy(key + 1, kde, kde_len);
    1371                 :        186 :                 WPA_PUT_BE16(key->key_data_length, kde_len);
    1372 [ +  + ][ +  - ]:        662 :         } else if (encr && kde) {
    1373                 :        407 :                 buf = os_zalloc(key_data_len);
    1374         [ -  + ]:        407 :                 if (buf == NULL) {
    1375                 :          0 :                         os_free(hdr);
    1376                 :          0 :                         return;
    1377                 :            :                 }
    1378                 :        407 :                 pos = buf;
    1379                 :        407 :                 os_memcpy(pos, kde, kde_len);
    1380                 :        407 :                 pos += kde_len;
    1381                 :            : 
    1382         [ +  + ]:        407 :                 if (pad_len)
    1383                 :        346 :                         *pos++ = 0xdd;
    1384                 :            : 
    1385                 :        407 :                 wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data",
    1386                 :            :                                 buf, key_data_len);
    1387 [ +  + ][ +  + ]:        407 :                 if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
    1388         [ +  + ]:         25 :                     sm->wpa_key_mgmt == WPA_KEY_MGMT_OSEN ||
    1389                 :            :                     version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
    1390         [ -  + ]:        398 :                         if (aes_wrap(sm->PTK.kek, (key_data_len - 8) / 8, buf,
    1391                 :            :                                      (u8 *) (key + 1))) {
    1392                 :          0 :                                 os_free(hdr);
    1393                 :          0 :                                 os_free(buf);
    1394                 :          0 :                                 return;
    1395                 :            :                         }
    1396                 :        398 :                         WPA_PUT_BE16(key->key_data_length, key_data_len);
    1397                 :            :                 } else {
    1398                 :            :                         u8 ek[32];
    1399                 :          9 :                         os_memcpy(key->key_iv,
    1400                 :            :                                   sm->group->Counter + WPA_NONCE_LEN - 16, 16);
    1401                 :          9 :                         inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
    1402                 :          9 :                         os_memcpy(ek, key->key_iv, 16);
    1403                 :          9 :                         os_memcpy(ek + 16, sm->PTK.kek, 16);
    1404                 :          9 :                         os_memcpy(key + 1, buf, key_data_len);
    1405                 :          9 :                         rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len);
    1406                 :          9 :                         WPA_PUT_BE16(key->key_data_length, key_data_len);
    1407                 :            :                 }
    1408                 :        407 :                 os_free(buf);
    1409                 :            :         }
    1410                 :            : 
    1411         [ +  + ]:        848 :         if (key_info & WPA_KEY_INFO_MIC) {
    1412         [ -  + ]:        416 :                 if (!sm->PTK_valid) {
    1413                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
    1414                 :            :                                         "PTK not valid when sending EAPOL-Key "
    1415                 :            :                                         "frame");
    1416                 :          0 :                         os_free(hdr);
    1417                 :          0 :                         return;
    1418                 :            :                 }
    1419                 :        416 :                 wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len,
    1420                 :        416 :                                   key->key_mic);
    1421                 :            : #ifdef CONFIG_TESTING_OPTIONS
    1422 [ -  + ][ +  + ]:        416 :                 if (!pairwise &&
    1423         [ #  # ]:          0 :                     wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0d &&
    1424                 :          0 :                     drand48() <
    1425                 :          0 :                     wpa_auth->conf.corrupt_gtk_rekey_mic_probability) {
    1426                 :          0 :                         wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
    1427                 :            :                                         "Corrupting group EAPOL-Key Key MIC");
    1428                 :          0 :                         key->key_mic[0]++;
    1429                 :            :                 }
    1430                 :            : #endif /* CONFIG_TESTING_OPTIONS */
    1431                 :            :         }
    1432                 :            : 
    1433                 :        848 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx,
    1434                 :            :                            1);
    1435                 :        848 :         wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len,
    1436                 :        848 :                             sm->pairwise_set);
    1437                 :        848 :         os_free(hdr);
    1438                 :            : }
    1439                 :            : 
    1440                 :            : 
    1441                 :        845 : static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
    1442                 :            :                            struct wpa_state_machine *sm, int key_info,
    1443                 :            :                            const u8 *key_rsc, const u8 *nonce,
    1444                 :            :                            const u8 *kde, size_t kde_len,
    1445                 :            :                            int keyidx, int encr)
    1446                 :            : {
    1447                 :            :         int timeout_ms;
    1448                 :        845 :         int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
    1449                 :            :         int ctr;
    1450                 :            : 
    1451         [ -  + ]:        845 :         if (sm == NULL)
    1452                 :        845 :                 return;
    1453                 :            : 
    1454                 :        845 :         __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len,
    1455                 :            :                          keyidx, encr, 0);
    1456                 :            : 
    1457         [ +  + ]:        845 :         ctr = pairwise ? sm->TimeoutCtr : sm->GTimeoutCtr;
    1458 [ +  + ][ +  + ]:        845 :         if (ctr == 1 && wpa_auth->conf.tx_status)
    1459         [ +  + ]:        813 :                 timeout_ms = pairwise ? eapol_key_timeout_first :
    1460                 :            :                         eapol_key_timeout_first_group;
    1461                 :            :         else
    1462                 :         32 :                 timeout_ms = eapol_key_timeout_subseq;
    1463 [ +  + ][ +  + ]:        845 :         if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC))
                 [ +  + ]
    1464                 :        411 :                 sm->pending_1_of_4_timeout = 1;
    1465                 :        845 :         wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry "
    1466                 :            :                    "counter %d)", timeout_ms, ctr);
    1467                 :        845 :         eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
    1468                 :            :                                wpa_send_eapol_timeout, wpa_auth, sm);
    1469                 :            : }
    1470                 :            : 
    1471                 :            : 
    1472                 :        858 : static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
    1473                 :            : {
    1474                 :            :         struct ieee802_1x_hdr *hdr;
    1475                 :            :         struct wpa_eapol_key *key;
    1476                 :            :         u16 key_info;
    1477                 :        858 :         int ret = 0;
    1478                 :            :         u8 mic[16];
    1479                 :            : 
    1480         [ -  + ]:        858 :         if (data_len < sizeof(*hdr) + sizeof(*key))
    1481                 :          0 :                 return -1;
    1482                 :            : 
    1483                 :        858 :         hdr = (struct ieee802_1x_hdr *) data;
    1484                 :        858 :         key = (struct wpa_eapol_key *) (hdr + 1);
    1485                 :        858 :         key_info = WPA_GET_BE16(key->key_info);
    1486                 :        858 :         os_memcpy(mic, key->key_mic, 16);
    1487                 :        858 :         os_memset(key->key_mic, 0, 16);
    1488         [ +  - ]:        858 :         if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK,
    1489         [ +  + ]:        858 :                               data, data_len, key->key_mic) ||
    1490                 :        858 :             os_memcmp(mic, key->key_mic, 16) != 0)
    1491                 :         39 :                 ret = -1;
    1492                 :        858 :         os_memcpy(key->key_mic, mic, 16);
    1493                 :        858 :         return ret;
    1494                 :            : }
    1495                 :            : 
    1496                 :            : 
    1497                 :       2353 : void wpa_remove_ptk(struct wpa_state_machine *sm)
    1498                 :            : {
    1499                 :       2353 :         sm->PTK_valid = FALSE;
    1500                 :       2353 :         os_memset(&sm->PTK, 0, sizeof(sm->PTK));
    1501                 :       2353 :         wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL, 0);
    1502                 :       2353 :         sm->pairwise_set = FALSE;
    1503                 :       2353 :         eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
    1504                 :       2353 : }
    1505                 :            : 
    1506                 :            : 
    1507                 :       2093 : int wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event)
    1508                 :            : {
    1509                 :       2093 :         int remove_ptk = 1;
    1510                 :            : 
    1511         [ +  + ]:       2093 :         if (sm == NULL)
    1512                 :       1279 :                 return -1;
    1513                 :            : 
    1514                 :        814 :         wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    1515                 :            :                          "event %d notification", event);
    1516                 :            : 
    1517   [ +  +  +  +  :        814 :         switch (event) {
                      - ]
    1518                 :            :         case WPA_AUTH:
    1519                 :            :         case WPA_ASSOC:
    1520                 :        430 :                 break;
    1521                 :            :         case WPA_DEAUTH:
    1522                 :            :         case WPA_DISASSOC:
    1523                 :        342 :                 sm->DeauthenticationRequest = TRUE;
    1524                 :        342 :                 break;
    1525                 :            :         case WPA_REAUTH:
    1526                 :            :         case WPA_REAUTH_EAPOL:
    1527         [ -  + ]:         26 :                 if (!sm->started) {
    1528                 :            :                         /*
    1529                 :            :                          * When using WPS, we may end up here if the STA
    1530                 :            :                          * manages to re-associate without the previous STA
    1531                 :            :                          * entry getting removed. Consequently, we need to make
    1532                 :            :                          * sure that the WPA state machines gets initialized
    1533                 :            :                          * properly at this point.
    1534                 :            :                          */
    1535                 :          0 :                         wpa_printf(MSG_DEBUG, "WPA state machine had not been "
    1536                 :            :                                    "started - initialize now");
    1537                 :          0 :                         sm->started = 1;
    1538                 :          0 :                         sm->Init = TRUE;
    1539         [ #  # ]:          0 :                         if (wpa_sm_step(sm) == 1)
    1540                 :          0 :                                 return 1; /* should not really happen */
    1541                 :          0 :                         sm->Init = FALSE;
    1542                 :          0 :                         sm->AuthenticationRequest = TRUE;
    1543                 :          0 :                         break;
    1544                 :            :                 }
    1545         [ -  + ]:         26 :                 if (sm->GUpdateStationKeys) {
    1546                 :            :                         /*
    1547                 :            :                          * Reauthentication cancels the pending group key
    1548                 :            :                          * update for this STA.
    1549                 :            :                          */
    1550                 :          0 :                         sm->group->GKeyDoneStations--;
    1551                 :          0 :                         sm->GUpdateStationKeys = FALSE;
    1552                 :          0 :                         sm->PtkGroupInit = TRUE;
    1553                 :            :                 }
    1554                 :         26 :                 sm->ReAuthenticationRequest = TRUE;
    1555                 :         26 :                 break;
    1556                 :            :         case WPA_ASSOC_FT:
    1557                 :            : #ifdef CONFIG_IEEE80211R
    1558                 :         16 :                 wpa_printf(MSG_DEBUG, "FT: Retry PTK configuration "
    1559                 :            :                            "after association");
    1560                 :         16 :                 wpa_ft_install_ptk(sm);
    1561                 :            : 
    1562                 :            :                 /* Using FT protocol, not WPA auth state machine */
    1563                 :         16 :                 sm->ft_completed = 1;
    1564                 :         16 :                 return 0;
    1565                 :            : #else /* CONFIG_IEEE80211R */
    1566                 :            :                 break;
    1567                 :            : #endif /* CONFIG_IEEE80211R */
    1568                 :            :         }
    1569                 :            : 
    1570                 :            : #ifdef CONFIG_IEEE80211R
    1571                 :        798 :         sm->ft_completed = 0;
    1572                 :            : #endif /* CONFIG_IEEE80211R */
    1573                 :            : 
    1574                 :            : #ifdef CONFIG_IEEE80211W
    1575 [ +  + ][ -  + ]:        798 :         if (sm->mgmt_frame_prot && event == WPA_AUTH)
    1576                 :          0 :                 remove_ptk = 0;
    1577                 :            : #endif /* CONFIG_IEEE80211W */
    1578                 :            : 
    1579         [ +  - ]:        798 :         if (remove_ptk) {
    1580                 :        798 :                 sm->PTK_valid = FALSE;
    1581                 :        798 :                 os_memset(&sm->PTK, 0, sizeof(sm->PTK));
    1582                 :            : 
    1583         [ +  + ]:        798 :                 if (event != WPA_REAUTH_EAPOL)
    1584                 :        772 :                         wpa_remove_ptk(sm);
    1585                 :            :         }
    1586                 :            : 
    1587                 :       2093 :         return wpa_sm_step(sm);
    1588                 :            : }
    1589                 :            : 
    1590                 :            : 
    1591                 :        740 : SM_STATE(WPA_PTK, INITIALIZE)
    1592                 :            : {
    1593 [ -  + ][ #  # ]:        740 :         SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk);
    1594         [ +  + ]:        740 :         if (sm->Init) {
    1595                 :            :                 /* Init flag is not cleared here, so avoid busy
    1596                 :            :                  * loop by claiming nothing changed. */
    1597                 :        398 :                 sm->changed = FALSE;
    1598                 :            :         }
    1599                 :            : 
    1600                 :        740 :         sm->keycount = 0;
    1601         [ -  + ]:        740 :         if (sm->GUpdateStationKeys)
    1602                 :          0 :                 sm->group->GKeyDoneStations--;
    1603                 :        740 :         sm->GUpdateStationKeys = FALSE;
    1604         [ +  + ]:        740 :         if (sm->wpa == WPA_VERSION_WPA)
    1605                 :         14 :                 sm->PInitAKeys = FALSE;
    1606                 :            :         if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and
    1607                 :            :                * Local AA > Remote AA)) */) {
    1608                 :        740 :                 sm->Pair = TRUE;
    1609                 :            :         }
    1610                 :        740 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0);
    1611                 :        740 :         wpa_remove_ptk(sm);
    1612                 :        740 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
    1613                 :        740 :         sm->TimeoutCtr = 0;
    1614         [ +  + ]:        740 :         if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
    1615                 :        394 :                 wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
    1616                 :            :                                    WPA_EAPOL_authorized, 0);
    1617                 :            :         }
    1618                 :        740 : }
    1619                 :            : 
    1620                 :            : 
    1621                 :          7 : SM_STATE(WPA_PTK, DISCONNECT)
    1622                 :            : {
    1623 [ -  + ][ #  # ]:          7 :         SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk);
    1624                 :          7 :         sm->Disconnect = FALSE;
    1625                 :          7 :         wpa_sta_disconnect(sm->wpa_auth, sm->addr);
    1626                 :          7 : }
    1627                 :            : 
    1628                 :            : 
    1629                 :        342 : SM_STATE(WPA_PTK, DISCONNECTED)
    1630                 :            : {
    1631 [ -  + ][ #  # ]:        342 :         SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk);
    1632                 :        342 :         sm->DeauthenticationRequest = FALSE;
    1633                 :        342 : }
    1634                 :            : 
    1635                 :            : 
    1636                 :        398 : SM_STATE(WPA_PTK, AUTHENTICATION)
    1637                 :            : {
    1638 [ -  + ][ #  # ]:        398 :         SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk);
    1639                 :        398 :         os_memset(&sm->PTK, 0, sizeof(sm->PTK));
    1640                 :        398 :         sm->PTK_valid = FALSE;
    1641                 :        398 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto,
    1642                 :            :                            1);
    1643                 :        398 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1);
    1644                 :        398 :         sm->AuthenticationRequest = FALSE;
    1645                 :        398 : }
    1646                 :            : 
    1647                 :            : 
    1648                 :        440 : static void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth,
    1649                 :            :                                   struct wpa_group *group)
    1650                 :            : {
    1651         [ +  + ]:        440 :         if (group->first_sta_seen)
    1652                 :        440 :                 return;
    1653                 :            :         /*
    1654                 :            :          * System has run bit further than at the time hostapd was started
    1655                 :            :          * potentially very early during boot up. This provides better chances
    1656                 :            :          * of collecting more randomness on embedded systems. Re-initialize the
    1657                 :            :          * GMK and Counter here to improve their strength if there was not
    1658                 :            :          * enough entropy available immediately after system startup.
    1659                 :            :          */
    1660                 :        285 :         wpa_printf(MSG_DEBUG, "WPA: Re-initialize GMK/Counter on first "
    1661                 :            :                    "station");
    1662                 :            :         if (random_pool_ready() != 1) {
    1663                 :            :                 wpa_printf(MSG_INFO, "WPA: Not enough entropy in random pool "
    1664                 :            :                            "to proceed - reject first 4-way handshake");
    1665                 :            :                 group->reject_4way_hs_for_entropy = TRUE;
    1666                 :            :         } else {
    1667                 :        285 :                 group->first_sta_seen = TRUE;
    1668                 :        285 :                 group->reject_4way_hs_for_entropy = FALSE;
    1669                 :            :         }
    1670                 :            : 
    1671                 :        285 :         wpa_group_init_gmk_and_counter(wpa_auth, group);
    1672                 :        285 :         wpa_gtk_update(wpa_auth, group);
    1673                 :        285 :         wpa_group_config_group_keys(wpa_auth, group);
    1674                 :            : }
    1675                 :            : 
    1676                 :            : 
    1677                 :        440 : SM_STATE(WPA_PTK, AUTHENTICATION2)
    1678                 :            : {
    1679 [ -  + ][ #  # ]:        440 :         SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk);
    1680                 :            : 
    1681                 :        440 :         wpa_group_ensure_init(sm->wpa_auth, sm->group);
    1682                 :        440 :         sm->ReAuthenticationRequest = FALSE;
    1683                 :            : 
    1684                 :            :         /*
    1685                 :            :          * Definition of ANonce selection in IEEE Std 802.11i-2004 is somewhat
    1686                 :            :          * ambiguous. The Authenticator state machine uses a counter that is
    1687                 :            :          * incremented by one for each 4-way handshake. However, the security
    1688                 :            :          * analysis of 4-way handshake points out that unpredictable nonces
    1689                 :            :          * help in preventing precomputation attacks. Instead of the state
    1690                 :            :          * machine definition, use an unpredictable nonce value here to provide
    1691                 :            :          * stronger protection against potential precomputation attacks.
    1692                 :            :          */
    1693         [ -  + ]:        440 :         if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
    1694                 :          0 :                 wpa_printf(MSG_ERROR, "WPA: Failed to get random data for "
    1695                 :            :                            "ANonce.");
    1696                 :          0 :                 sm->Disconnect = TRUE;
    1697                 :        440 :                 return;
    1698                 :            :         }
    1699                 :        440 :         wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce,
    1700                 :            :                     WPA_NONCE_LEN);
    1701                 :            :         /* IEEE 802.11i does not clear TimeoutCtr here, but this is more
    1702                 :            :          * logical place than INITIALIZE since AUTHENTICATION2 can be
    1703                 :            :          * re-entered on ReAuthenticationRequest without going through
    1704                 :            :          * INITIALIZE. */
    1705                 :        440 :         sm->TimeoutCtr = 0;
    1706                 :            : }
    1707                 :            : 
    1708                 :            : 
    1709                 :        180 : SM_STATE(WPA_PTK, INITPMK)
    1710                 :            : {
    1711                 :            :         u8 msk[2 * PMK_LEN];
    1712                 :        180 :         size_t len = 2 * PMK_LEN;
    1713                 :            : 
    1714 [ -  + ][ #  # ]:        180 :         SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk);
    1715                 :            : #ifdef CONFIG_IEEE80211R
    1716                 :        180 :         sm->xxkey_len = 0;
    1717                 :            : #endif /* CONFIG_IEEE80211R */
    1718         [ +  + ]:        180 :         if (sm->pmksa) {
    1719                 :          5 :                 wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache");
    1720                 :          5 :                 os_memcpy(sm->PMK, sm->pmksa->pmk, PMK_LEN);
    1721         [ +  - ]:        175 :         } else if (wpa_auth_get_msk(sm->wpa_auth, sm->addr, msk, &len) == 0) {
    1722                 :        175 :                 wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine "
    1723                 :            :                            "(len=%lu)", (unsigned long) len);
    1724                 :        175 :                 os_memcpy(sm->PMK, msk, PMK_LEN);
    1725                 :            : #ifdef CONFIG_IEEE80211R
    1726         [ +  - ]:        175 :                 if (len >= 2 * PMK_LEN) {
    1727                 :        175 :                         os_memcpy(sm->xxkey, msk + PMK_LEN, PMK_LEN);
    1728                 :        175 :                         sm->xxkey_len = PMK_LEN;
    1729                 :            :                 }
    1730                 :            : #endif /* CONFIG_IEEE80211R */
    1731                 :            :         } else {
    1732                 :          0 :                 wpa_printf(MSG_DEBUG, "WPA: Could not get PMK");
    1733                 :            :         }
    1734                 :            : 
    1735                 :        180 :         sm->req_replay_counter_used = 0;
    1736                 :            :         /* IEEE 802.11i does not set keyRun to FALSE, but not doing this
    1737                 :            :          * will break reauthentication since EAPOL state machines may not be
    1738                 :            :          * get into AUTHENTICATING state that clears keyRun before WPA state
    1739                 :            :          * machine enters AUTHENTICATION2 state and goes immediately to INITPMK
    1740                 :            :          * state and takes PMK from the previously used AAA Key. This will
    1741                 :            :          * eventually fail in 4-Way Handshake because Supplicant uses PMK
    1742                 :            :          * derived from the new AAA Key. Setting keyRun = FALSE here seems to
    1743                 :            :          * be good workaround for this issue. */
    1744                 :        180 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0);
    1745                 :        180 : }
    1746                 :            : 
    1747                 :            : 
    1748                 :        231 : SM_STATE(WPA_PTK, INITPSK)
    1749                 :            : {
    1750                 :            :         const u8 *psk;
    1751 [ -  + ][ #  # ]:        231 :         SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk);
    1752                 :        231 :         psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, NULL);
    1753         [ +  - ]:        231 :         if (psk) {
    1754                 :        231 :                 os_memcpy(sm->PMK, psk, PMK_LEN);
    1755                 :            : #ifdef CONFIG_IEEE80211R
    1756                 :        231 :                 os_memcpy(sm->xxkey, psk, PMK_LEN);
    1757                 :        231 :                 sm->xxkey_len = PMK_LEN;
    1758                 :            : #endif /* CONFIG_IEEE80211R */
    1759                 :            :         }
    1760                 :        231 :         sm->req_replay_counter_used = 0;
    1761                 :        231 : }
    1762                 :            : 
    1763                 :            : 
    1764                 :        439 : SM_STATE(WPA_PTK, PTKSTART)
    1765                 :            : {
    1766                 :        439 :         u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL;
    1767                 :        439 :         size_t pmkid_len = 0;
    1768                 :            : 
    1769 [ -  + ][ #  # ]:        439 :         SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk);
    1770                 :        439 :         sm->PTKRequest = FALSE;
    1771                 :        439 :         sm->TimeoutEvt = FALSE;
    1772                 :            : 
    1773                 :        439 :         sm->TimeoutCtr++;
    1774         [ +  + ]:        439 :         if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
    1775                 :            :                 /* No point in sending the EAPOL-Key - we will disconnect
    1776                 :            :                  * immediately following this. */
    1777                 :        439 :                 return;
    1778                 :            :         }
    1779                 :            : 
    1780                 :        432 :         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    1781                 :            :                         "sending 1/4 msg of 4-Way Handshake");
    1782                 :            :         /*
    1783                 :            :          * TODO: Could add PMKID even with WPA2-PSK, but only if there is only
    1784                 :            :          * one possible PSK for this STA.
    1785                 :            :          */
    1786   [ +  +  +  + ]:        856 :         if (sm->wpa == WPA_VERSION_WPA2 &&
    1787         [ +  + ]:        602 :             wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) &&
    1788                 :        178 :             sm->wpa_key_mgmt != WPA_KEY_MGMT_OSEN) {
    1789                 :        177 :                 pmkid = buf;
    1790                 :        177 :                 pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
    1791                 :        177 :                 pmkid[0] = WLAN_EID_VENDOR_SPECIFIC;
    1792                 :        177 :                 pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN;
    1793                 :        177 :                 RSN_SELECTOR_PUT(&pmkid[2], RSN_KEY_DATA_PMKID);
    1794         [ +  + ]:        177 :                 if (sm->pmksa)
    1795                 :          5 :                         os_memcpy(&pmkid[2 + RSN_SELECTOR_LEN],
    1796                 :            :                                   sm->pmksa->pmkid, PMKID_LEN);
    1797                 :            :                 else {
    1798                 :            :                         /*
    1799                 :            :                          * Calculate PMKID since no PMKSA cache entry was
    1800                 :            :                          * available with pre-calculated PMKID.
    1801                 :            :                          */
    1802                 :        172 :                         rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr,
    1803                 :        172 :                                   sm->addr, &pmkid[2 + RSN_SELECTOR_LEN],
    1804                 :            :                                   wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
    1805                 :            :                 }
    1806                 :            :         }
    1807                 :        432 :         wpa_send_eapol(sm->wpa_auth, sm,
    1808                 :            :                        WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL,
    1809                 :        432 :                        sm->ANonce, pmkid, pmkid_len, 0, 0);
    1810                 :            : }
    1811                 :            : 
    1812                 :            : 
    1813                 :        443 : static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk,
    1814                 :            :                           struct wpa_ptk *ptk)
    1815                 :            : {
    1816         [ +  + ]:        443 :         size_t ptk_len = sm->pairwise != WPA_CIPHER_TKIP ? 48 : 64;
    1817                 :            : #ifdef CONFIG_IEEE80211R
    1818         [ +  + ]:        443 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
    1819                 :          8 :                 return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len);
    1820                 :            : #endif /* CONFIG_IEEE80211R */
    1821                 :            : 
    1822                 :        435 :         wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
    1823                 :        435 :                        sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
    1824                 :            :                        (u8 *) ptk, ptk_len,
    1825                 :            :                        wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
    1826                 :            : 
    1827                 :        443 :         return 0;
    1828                 :            : }
    1829                 :            : 
    1830                 :            : 
    1831                 :        432 : SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
    1832                 :            : {
    1833                 :            :         struct wpa_ptk PTK;
    1834                 :        432 :         int ok = 0;
    1835                 :        432 :         const u8 *pmk = NULL;
    1836                 :            : 
    1837 [ -  + ][ #  # ]:        432 :         SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
    1838                 :        432 :         sm->EAPOLKeyReceived = FALSE;
    1839                 :        432 :         sm->update_snonce = FALSE;
    1840                 :            : 
    1841                 :            :         /* WPA with IEEE 802.1X: use the derived PMK from EAP
    1842                 :            :          * WPA-PSK: iterate through possible PSKs and select the one matching
    1843                 :            :          * the packet */
    1844                 :            :         for (;;) {
    1845         [ +  + ]:        471 :                 if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
    1846                 :        291 :                         pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
    1847                 :        291 :                                                sm->p2p_dev_addr, pmk);
    1848         [ +  + ]:        291 :                         if (pmk == NULL)
    1849                 :         28 :                                 break;
    1850                 :            :                 } else
    1851                 :        180 :                         pmk = sm->PMK;
    1852                 :            : 
    1853                 :        443 :                 wpa_derive_ptk(sm, pmk, &PTK);
    1854                 :            : 
    1855         [ +  + ]:        443 :                 if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key,
    1856                 :            :                                        sm->last_rx_eapol_key_len) == 0) {
    1857                 :        404 :                         ok = 1;
    1858                 :        404 :                         break;
    1859                 :            :                 }
    1860                 :            : 
    1861         [ -  + ]:         39 :                 if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt))
    1862                 :          0 :                         break;
    1863                 :         39 :         }
    1864                 :            : 
    1865         [ +  + ]:        432 :         if (!ok) {
    1866                 :         28 :                 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    1867                 :            :                                 "invalid MIC in msg 2/4 of 4-Way Handshake");
    1868                 :         28 :                 return;
    1869                 :            :         }
    1870                 :            : 
    1871                 :            : #ifdef CONFIG_IEEE80211R
    1872 [ +  + ][ +  + ]:        404 :         if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
    1873                 :            :                 /*
    1874                 :            :                  * Verify that PMKR1Name from EAPOL-Key message 2/4 matches
    1875                 :            :                  * with the value we derived.
    1876                 :            :                  */
    1877         [ -  + ]:          8 :                 if (os_memcmp(sm->sup_pmk_r1_name, sm->pmk_r1_name,
    1878                 :            :                               WPA_PMK_NAME_LEN) != 0) {
    1879                 :          0 :                         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    1880                 :            :                                         "PMKR1Name mismatch in FT 4-way "
    1881                 :            :                                         "handshake");
    1882                 :          0 :                         wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from "
    1883                 :            :                                     "Supplicant",
    1884                 :          0 :                                     sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN);
    1885                 :          0 :                         wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
    1886                 :          0 :                                     sm->pmk_r1_name, WPA_PMK_NAME_LEN);
    1887                 :          0 :                         return;
    1888                 :            :                 }
    1889                 :            :         }
    1890                 :            : #endif /* CONFIG_IEEE80211R */
    1891                 :            : 
    1892                 :        404 :         sm->pending_1_of_4_timeout = 0;
    1893                 :        404 :         eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
    1894                 :            : 
    1895         [ +  + ]:        404 :         if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
    1896                 :            :                 /* PSK may have changed from the previous choice, so update
    1897                 :            :                  * state machine data based on whatever PSK was selected here.
    1898                 :            :                  */
    1899                 :        224 :                 os_memcpy(sm->PMK, pmk, PMK_LEN);
    1900                 :            :         }
    1901                 :            : 
    1902                 :        404 :         sm->MICVerified = TRUE;
    1903                 :            : 
    1904                 :        404 :         os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
    1905                 :        432 :         sm->PTK_valid = TRUE;
    1906                 :            : }
    1907                 :            : 
    1908                 :            : 
    1909                 :        404 : SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2)
    1910                 :            : {
    1911 [ -  + ][ #  # ]:        404 :         SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk);
    1912                 :        404 :         sm->TimeoutCtr = 0;
    1913                 :        404 : }
    1914                 :            : 
    1915                 :            : 
    1916                 :            : #ifdef CONFIG_IEEE80211W
    1917                 :            : 
    1918                 :        405 : static int ieee80211w_kde_len(struct wpa_state_machine *sm)
    1919                 :            : {
    1920         [ +  + ]:        405 :         if (sm->mgmt_frame_prot) {
    1921                 :         16 :                 return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde);
    1922                 :            :         }
    1923                 :            : 
    1924                 :        405 :         return 0;
    1925                 :            : }
    1926                 :            : 
    1927                 :            : 
    1928                 :        405 : static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
    1929                 :            : {
    1930                 :            :         struct wpa_igtk_kde igtk;
    1931                 :        405 :         struct wpa_group *gsm = sm->group;
    1932                 :            :         u8 rsc[WPA_KEY_RSC_LEN];
    1933                 :            : 
    1934         [ +  + ]:        405 :         if (!sm->mgmt_frame_prot)
    1935                 :        389 :                 return pos;
    1936                 :            : 
    1937                 :         16 :         igtk.keyid[0] = gsm->GN_igtk;
    1938                 :         16 :         igtk.keyid[1] = 0;
    1939   [ +  -  -  + ]:         32 :         if (gsm->wpa_group_state != WPA_GROUP_SETKEYSDONE ||
    1940                 :         16 :             wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, rsc) < 0)
    1941                 :          0 :                 os_memset(igtk.pn, 0, sizeof(igtk.pn));
    1942                 :            :         else
    1943                 :         16 :                 os_memcpy(igtk.pn, rsc, sizeof(igtk.pn));
    1944                 :         16 :         os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
    1945         [ +  + ]:         16 :         if (sm->wpa_auth->conf.disable_gtk) {
    1946                 :            :                 /*
    1947                 :            :                  * Provide unique random IGTK to each STA to prevent use of
    1948                 :            :                  * IGTK in the BSS.
    1949                 :            :                  */
    1950         [ -  + ]:          1 :                 if (random_get_bytes(igtk.igtk, WPA_IGTK_LEN) < 0)
    1951                 :          0 :                         return pos;
    1952                 :            :         }
    1953                 :         16 :         pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
    1954                 :            :                           (const u8 *) &igtk, sizeof(igtk), NULL, 0);
    1955                 :            : 
    1956                 :        405 :         return pos;
    1957                 :            : }
    1958                 :            : 
    1959                 :            : #else /* CONFIG_IEEE80211W */
    1960                 :            : 
    1961                 :            : static int ieee80211w_kde_len(struct wpa_state_machine *sm)
    1962                 :            : {
    1963                 :            :         return 0;
    1964                 :            : }
    1965                 :            : 
    1966                 :            : 
    1967                 :            : static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
    1968                 :            : {
    1969                 :            :         return pos;
    1970                 :            : }
    1971                 :            : 
    1972                 :            : #endif /* CONFIG_IEEE80211W */
    1973                 :            : 
    1974                 :            : 
    1975                 :        404 : SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
    1976                 :            : {
    1977                 :            :         u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32];
    1978                 :            :         size_t gtk_len, kde_len;
    1979                 :        404 :         struct wpa_group *gsm = sm->group;
    1980                 :            :         u8 *wpa_ie;
    1981                 :        404 :         int wpa_ie_len, secure, keyidx, encr = 0;
    1982                 :            : 
    1983 [ -  + ][ #  # ]:        404 :         SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
    1984                 :        404 :         sm->TimeoutEvt = FALSE;
    1985                 :            : 
    1986                 :        404 :         sm->TimeoutCtr++;
    1987         [ -  + ]:        404 :         if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
    1988                 :            :                 /* No point in sending the EAPOL-Key - we will disconnect
    1989                 :            :                  * immediately following this. */
    1990                 :          0 :                 return;
    1991                 :            :         }
    1992                 :            : 
    1993                 :            :         /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE],
    1994                 :            :            GTK[GN], IGTK, [FTIE], [TIE * 2])
    1995                 :            :          */
    1996                 :        404 :         os_memset(rsc, 0, WPA_KEY_RSC_LEN);
    1997                 :        404 :         wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc);
    1998                 :            :         /* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */
    1999                 :        404 :         wpa_ie = sm->wpa_auth->wpa_ie;
    2000                 :        404 :         wpa_ie_len = sm->wpa_auth->wpa_ie_len;
    2001 [ +  + ][ +  + ]:        404 :         if (sm->wpa == WPA_VERSION_WPA &&
    2002         [ +  - ]:          3 :             (sm->wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
    2003         [ +  - ]:          3 :             wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {
    2004                 :            :                 /* WPA-only STA, remove RSN IE */
    2005                 :          3 :                 wpa_ie = wpa_ie + wpa_ie[1] + 2;
    2006                 :          3 :                 wpa_ie_len = wpa_ie[1] + 2;
    2007                 :            :         }
    2008                 :        404 :         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2009                 :            :                         "sending 3/4 msg of 4-Way Handshake");
    2010         [ +  + ]:        404 :         if (sm->wpa == WPA_VERSION_WPA2) {
    2011                 :            :                 /* WPA2 send GTK in the 4-way handshake */
    2012                 :        396 :                 secure = 1;
    2013                 :        396 :                 gtk = gsm->GTK[gsm->GN - 1];
    2014                 :        396 :                 gtk_len = gsm->GTK_len;
    2015         [ +  + ]:        396 :                 if (sm->wpa_auth->conf.disable_gtk) {
    2016                 :            :                         /*
    2017                 :            :                          * Provide unique random GTK to each STA to prevent use
    2018                 :            :                          * of GTK in the BSS.
    2019                 :            :                          */
    2020         [ -  + ]:          1 :                         if (random_get_bytes(dummy_gtk, gtk_len) < 0)
    2021                 :          0 :                                 return;
    2022                 :          1 :                         gtk = dummy_gtk;
    2023                 :            :                 }
    2024                 :        396 :                 keyidx = gsm->GN;
    2025                 :        396 :                 _rsc = rsc;
    2026                 :        396 :                 encr = 1;
    2027                 :            :         } else {
    2028                 :            :                 /* WPA does not include GTK in msg 3/4 */
    2029                 :          8 :                 secure = 0;
    2030                 :          8 :                 gtk = NULL;
    2031                 :          8 :                 gtk_len = 0;
    2032                 :          8 :                 keyidx = 0;
    2033                 :          8 :                 _rsc = NULL;
    2034         [ -  + ]:          8 :                 if (sm->rx_eapol_key_secure) {
    2035                 :            :                         /*
    2036                 :            :                          * It looks like Windows 7 supplicant tries to use
    2037                 :            :                          * Secure bit in msg 2/4 after having reported Michael
    2038                 :            :                          * MIC failure and it then rejects the 4-way handshake
    2039                 :            :                          * if msg 3/4 does not set Secure bit. Work around this
    2040                 :            :                          * by setting the Secure bit here even in the case of
    2041                 :            :                          * WPA if the supplicant used it first.
    2042                 :            :                          */
    2043                 :          0 :                         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2044                 :            :                                         "STA used Secure bit in WPA msg 2/4 - "
    2045                 :            :                                         "set Secure for 3/4 as workaround");
    2046                 :          0 :                         secure = 1;
    2047                 :            :                 }
    2048                 :            :         }
    2049                 :            : 
    2050                 :        404 :         kde_len = wpa_ie_len + ieee80211w_kde_len(sm);
    2051         [ +  + ]:        404 :         if (gtk)
    2052                 :        396 :                 kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len;
    2053                 :            : #ifdef CONFIG_IEEE80211R
    2054         [ +  + ]:        404 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
    2055                 :          8 :                 kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */
    2056                 :          8 :                 kde_len += 300; /* FTIE + 2 * TIE */
    2057                 :            :         }
    2058                 :            : #endif /* CONFIG_IEEE80211R */
    2059                 :            : #ifdef CONFIG_P2P
    2060         [ +  + ]:         96 :         if (WPA_GET_BE32(sm->ip_addr) > 0)
    2061                 :         50 :                 kde_len += 2 + RSN_SELECTOR_LEN + 3 * 4;
    2062                 :            : #endif /* CONFIG_P2P */
    2063                 :        404 :         kde = os_malloc(kde_len);
    2064         [ -  + ]:        404 :         if (kde == NULL)
    2065                 :          0 :                 return;
    2066                 :            : 
    2067                 :        404 :         pos = kde;
    2068                 :        404 :         os_memcpy(pos, wpa_ie, wpa_ie_len);
    2069                 :        404 :         pos += wpa_ie_len;
    2070                 :            : #ifdef CONFIG_IEEE80211R
    2071         [ +  + ]:        404 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
    2072                 :          8 :                 int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name);
    2073         [ -  + ]:          8 :                 if (res < 0) {
    2074                 :          0 :                         wpa_printf(MSG_ERROR, "FT: Failed to insert "
    2075                 :            :                                    "PMKR1Name into RSN IE in EAPOL-Key data");
    2076                 :          0 :                         os_free(kde);
    2077                 :          0 :                         return;
    2078                 :            :                 }
    2079                 :          8 :                 pos += res;
    2080                 :            :         }
    2081                 :            : #endif /* CONFIG_IEEE80211R */
    2082         [ +  + ]:        404 :         if (gtk) {
    2083                 :            :                 u8 hdr[2];
    2084                 :        396 :                 hdr[0] = keyidx & 0x03;
    2085                 :        396 :                 hdr[1] = 0;
    2086                 :        396 :                 pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
    2087                 :            :                                   gtk, gtk_len);
    2088                 :            :         }
    2089                 :        404 :         pos = ieee80211w_kde_add(sm, pos);
    2090                 :            : 
    2091                 :            : #ifdef CONFIG_IEEE80211R
    2092         [ +  + ]:        404 :         if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
    2093                 :            :                 int res;
    2094                 :            :                 struct wpa_auth_config *conf;
    2095                 :            : 
    2096                 :          8 :                 conf = &sm->wpa_auth->conf;
    2097                 :          8 :                 res = wpa_write_ftie(conf, conf->r0_key_holder,
    2098                 :            :                                      conf->r0_key_holder_len,
    2099                 :          8 :                                      NULL, NULL, pos, kde + kde_len - pos,
    2100                 :            :                                      NULL, 0);
    2101         [ -  + ]:          8 :                 if (res < 0) {
    2102                 :          0 :                         wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
    2103                 :            :                                    "into EAPOL-Key Key Data");
    2104                 :          0 :                         os_free(kde);
    2105                 :          0 :                         return;
    2106                 :            :                 }
    2107                 :          8 :                 pos += res;
    2108                 :            : 
    2109                 :            :                 /* TIE[ReassociationDeadline] (TU) */
    2110                 :          8 :                 *pos++ = WLAN_EID_TIMEOUT_INTERVAL;
    2111                 :          8 :                 *pos++ = 5;
    2112                 :          8 :                 *pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE;
    2113                 :          8 :                 WPA_PUT_LE32(pos, conf->reassociation_deadline);
    2114                 :          8 :                 pos += 4;
    2115                 :            : 
    2116                 :            :                 /* TIE[KeyLifetime] (seconds) */
    2117                 :          8 :                 *pos++ = WLAN_EID_TIMEOUT_INTERVAL;
    2118                 :          8 :                 *pos++ = 5;
    2119                 :          8 :                 *pos++ = WLAN_TIMEOUT_KEY_LIFETIME;
    2120                 :          8 :                 WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60);
    2121                 :          8 :                 pos += 4;
    2122                 :            :         }
    2123                 :            : #endif /* CONFIG_IEEE80211R */
    2124                 :            : #ifdef CONFIG_P2P
    2125         [ +  + ]:         96 :         if (WPA_GET_BE32(sm->ip_addr) > 0) {
    2126                 :            :                 u8 addr[3 * 4];
    2127                 :         50 :                 os_memcpy(addr, sm->ip_addr, 4);
    2128                 :         50 :                 os_memcpy(addr + 4, sm->wpa_auth->conf.ip_addr_mask, 4);
    2129                 :         50 :                 os_memcpy(addr + 8, sm->wpa_auth->conf.ip_addr_go, 4);
    2130                 :         50 :                 pos = wpa_add_kde(pos, WFA_KEY_DATA_IP_ADDR_ALLOC,
    2131                 :            :                                   addr, sizeof(addr), NULL, 0);
    2132                 :            :         }
    2133                 :            : #endif /* CONFIG_P2P */
    2134                 :            : 
    2135         [ +  + ]:        404 :         wpa_send_eapol(sm->wpa_auth, sm,
    2136                 :            :                        (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC |
    2137                 :            :                        WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |
    2138                 :            :                        WPA_KEY_INFO_KEY_TYPE,
    2139                 :        808 :                        _rsc, sm->ANonce, kde, pos - kde, keyidx, encr);
    2140                 :        404 :         os_free(kde);
    2141                 :            : }
    2142                 :            : 
    2143                 :            : 
    2144                 :        404 : SM_STATE(WPA_PTK, PTKINITDONE)
    2145                 :            : {
    2146 [ -  + ][ #  # ]:        404 :         SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk);
    2147                 :        404 :         sm->EAPOLKeyReceived = FALSE;
    2148         [ +  - ]:        404 :         if (sm->Pair) {
    2149                 :        404 :                 enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
    2150                 :        404 :                 int klen = wpa_cipher_key_len(sm->pairwise);
    2151         [ -  + ]:        404 :                 if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
    2152                 :        404 :                                      sm->PTK.tk1, klen)) {
    2153                 :          0 :                         wpa_sta_disconnect(sm->wpa_auth, sm->addr);
    2154                 :        404 :                         return;
    2155                 :            :                 }
    2156                 :            :                 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
    2157                 :        404 :                 sm->pairwise_set = TRUE;
    2158                 :            : 
    2159         [ -  + ]:        404 :                 if (sm->wpa_auth->conf.wpa_ptk_rekey) {
    2160                 :          0 :                         eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
    2161                 :          0 :                         eloop_register_timeout(sm->wpa_auth->conf.
    2162                 :            :                                                wpa_ptk_rekey, 0, wpa_rekey_ptk,
    2163                 :          0 :                                                sm->wpa_auth, sm);
    2164                 :            :                 }
    2165                 :            : 
    2166         [ +  + ]:        404 :                 if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
    2167                 :        224 :                         wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
    2168                 :            :                                            WPA_EAPOL_authorized, 1);
    2169                 :            :                 }
    2170                 :            :         }
    2171                 :            : 
    2172                 :            :         if (0 /* IBSS == TRUE */) {
    2173                 :            :                 sm->keycount++;
    2174                 :            :                 if (sm->keycount == 2) {
    2175                 :            :                         wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
    2176                 :            :                                            WPA_EAPOL_portValid, 1);
    2177                 :            :                 }
    2178                 :            :         } else {
    2179                 :        404 :                 wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid,
    2180                 :            :                                    1);
    2181                 :            :         }
    2182                 :        404 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0);
    2183                 :        404 :         wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1);
    2184         [ +  + ]:        404 :         if (sm->wpa == WPA_VERSION_WPA)
    2185                 :          8 :                 sm->PInitAKeys = TRUE;
    2186                 :            :         else
    2187                 :        396 :                 sm->has_GTK = TRUE;
    2188         [ +  + ]:        404 :         wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
    2189                 :            :                          "pairwise key handshake completed (%s)",
    2190                 :        404 :                          sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
    2191                 :            : 
    2192                 :            : #ifdef CONFIG_IEEE80211R
    2193                 :        404 :         wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr);
    2194                 :            : #endif /* CONFIG_IEEE80211R */
    2195                 :            : }
    2196                 :            : 
    2197                 :            : 
    2198                 :       9832 : SM_STEP(WPA_PTK)
    2199                 :            : {
    2200                 :       9832 :         struct wpa_authenticator *wpa_auth = sm->wpa_auth;
    2201                 :            : 
    2202         [ +  + ]:       9832 :         if (sm->Init)
    2203                 :        398 :                 SM_ENTER(WPA_PTK, INITIALIZE);
    2204         [ -  + ]:       9434 :         else if (sm->Disconnect
    2205                 :            :                  /* || FIX: dot11RSNAConfigSALifetime timeout */) {
    2206                 :          0 :                 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
    2207                 :            :                                 "WPA_PTK: sm->Disconnect");
    2208                 :          0 :                 SM_ENTER(WPA_PTK, DISCONNECT);
    2209                 :            :         }
    2210         [ +  + ]:       9434 :         else if (sm->DeauthenticationRequest)
    2211                 :        342 :                 SM_ENTER(WPA_PTK, DISCONNECTED);
    2212         [ +  + ]:       9092 :         else if (sm->AuthenticationRequest)
    2213                 :        398 :                 SM_ENTER(WPA_PTK, AUTHENTICATION);
    2214         [ +  + ]:       8694 :         else if (sm->ReAuthenticationRequest)
    2215                 :         42 :                 SM_ENTER(WPA_PTK, AUTHENTICATION2);
    2216         [ -  + ]:       8652 :         else if (sm->PTKRequest)
    2217                 :          0 :                 SM_ENTER(WPA_PTK, PTKSTART);
    2218   [ +  -  +  +  :       8652 :         else switch (sm->wpa_ptk_state) {
          +  +  +  +  +  
             +  +  +  - ]
    2219                 :            :         case WPA_PTK_INITIALIZE:
    2220                 :        848 :                 break;
    2221                 :            :         case WPA_PTK_DISCONNECT:
    2222                 :          0 :                 SM_ENTER(WPA_PTK, DISCONNECTED);
    2223                 :          0 :                 break;
    2224                 :            :         case WPA_PTK_DISCONNECTED:
    2225                 :        342 :                 SM_ENTER(WPA_PTK, INITIALIZE);
    2226                 :        342 :                 break;
    2227                 :            :         case WPA_PTK_AUTHENTICATION:
    2228                 :        398 :                 SM_ENTER(WPA_PTK, AUTHENTICATION2);
    2229                 :        398 :                 break;
    2230                 :            :         case WPA_PTK_AUTHENTICATION2:
    2231   [ +  +  +  + ]:       6657 :                 if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) &&
    2232                 :       3209 :                     wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
    2233                 :            :                                        WPA_EAPOL_keyRun) > 0)
    2234                 :        180 :                         SM_ENTER(WPA_PTK, INITPMK);
    2235         [ +  + ]:       3268 :                 else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)
    2236                 :            :                          /* FIX: && 802.1X::keyRun */)
    2237                 :        231 :                         SM_ENTER(WPA_PTK, INITPSK);
    2238                 :       3448 :                 break;
    2239                 :            :         case WPA_PTK_INITPMK:
    2240         [ +  - ]:        180 :                 if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
    2241                 :            :                                        WPA_EAPOL_keyAvailable) > 0)
    2242                 :        180 :                         SM_ENTER(WPA_PTK, PTKSTART);
    2243                 :            :                 else {
    2244                 :          0 :                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
    2245                 :          0 :                         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
    2246                 :            :                                         "INITPMK - keyAvailable = false");
    2247                 :          0 :                         SM_ENTER(WPA_PTK, DISCONNECT);
    2248                 :            :                 }
    2249                 :        180 :                 break;
    2250                 :            :         case WPA_PTK_INITPSK:
    2251         [ +  - ]:        231 :                 if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr,
    2252                 :            :                                      NULL))
    2253                 :        231 :                         SM_ENTER(WPA_PTK, PTKSTART);
    2254                 :            :                 else {
    2255                 :          0 :                         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
    2256                 :            :                                         "no PSK configured for the STA");
    2257                 :          0 :                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
    2258                 :          0 :                         SM_ENTER(WPA_PTK, DISCONNECT);
    2259                 :            :                 }
    2260                 :        231 :                 break;
    2261                 :            :         case WPA_PTK_PTKSTART:
    2262 [ +  + ][ +  - ]:        882 :                 if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
                 [ +  - ]
    2263                 :        432 :                     sm->EAPOLKeyPairwise)
    2264                 :        432 :                         SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
    2265         [ +  + ]:        450 :                 else if (sm->TimeoutCtr >
    2266                 :        450 :                          (int) dot11RSNAConfigPairwiseUpdateCount) {
    2267                 :          7 :                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
    2268                 :          7 :                         wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2269                 :            :                                          "PTKSTART: Retry limit %d reached",
    2270                 :            :                                          dot11RSNAConfigPairwiseUpdateCount);
    2271                 :          7 :                         SM_ENTER(WPA_PTK, DISCONNECT);
    2272         [ -  + ]:        443 :                 } else if (sm->TimeoutEvt)
    2273                 :          0 :                         SM_ENTER(WPA_PTK, PTKSTART);
    2274                 :        882 :                 break;
    2275                 :            :         case WPA_PTK_PTKCALCNEGOTIATING:
    2276         [ +  + ]:        460 :                 if (sm->MICVerified)
    2277                 :        404 :                         SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2);
    2278 [ -  + ][ #  # ]:         56 :                 else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
                 [ #  # ]
    2279                 :          0 :                          sm->EAPOLKeyPairwise)
    2280                 :          0 :                         SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
    2281         [ +  + ]:         56 :                 else if (sm->TimeoutEvt)
    2282                 :         28 :                         SM_ENTER(WPA_PTK, PTKSTART);
    2283                 :        460 :                 break;
    2284                 :            :         case WPA_PTK_PTKCALCNEGOTIATING2:
    2285                 :        404 :                 SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
    2286                 :        404 :                 break;
    2287                 :            :         case WPA_PTK_PTKINITNEGOTIATING:
    2288         [ -  + ]:        808 :                 if (sm->update_snonce)
    2289                 :          0 :                         SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
    2290 [ +  + ][ +  - ]:        808 :                 else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
                 [ +  - ]
    2291         [ +  - ]:        404 :                          sm->EAPOLKeyPairwise && sm->MICVerified)
    2292                 :        404 :                         SM_ENTER(WPA_PTK, PTKINITDONE);
    2293         [ -  + ]:        404 :                 else if (sm->TimeoutCtr >
    2294                 :        404 :                          (int) dot11RSNAConfigPairwiseUpdateCount) {
    2295                 :          0 :                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
    2296                 :          0 :                         wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2297                 :            :                                          "PTKINITNEGOTIATING: Retry limit %d "
    2298                 :            :                                          "reached",
    2299                 :            :                                          dot11RSNAConfigPairwiseUpdateCount);
    2300                 :          0 :                         SM_ENTER(WPA_PTK, DISCONNECT);
    2301         [ -  + ]:        404 :                 } else if (sm->TimeoutEvt)
    2302                 :          0 :                         SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
    2303                 :        808 :                 break;
    2304                 :            :         case WPA_PTK_PTKINITDONE:
    2305                 :        651 :                 break;
    2306                 :            :         }
    2307                 :       9832 : }
    2308                 :            : 
    2309                 :            : 
    2310                 :        407 : SM_STATE(WPA_PTK_GROUP, IDLE)
    2311                 :            : {
    2312 [ -  + ][ #  # ]:        407 :         SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group);
    2313         [ +  + ]:        407 :         if (sm->Init) {
    2314                 :            :                 /* Init flag is not cleared here, so avoid busy
    2315                 :            :                  * loop by claiming nothing changed. */
    2316                 :        398 :                 sm->changed = FALSE;
    2317                 :            :         }
    2318                 :        407 :         sm->GTimeoutCtr = 0;
    2319                 :        407 : }
    2320                 :            : 
    2321                 :            : 
    2322                 :          9 : SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
    2323                 :            : {
    2324                 :            :         u8 rsc[WPA_KEY_RSC_LEN];
    2325                 :          9 :         struct wpa_group *gsm = sm->group;
    2326                 :            :         u8 *kde, *pos, hdr[2];
    2327                 :            :         size_t kde_len;
    2328                 :            :         u8 *gtk, dummy_gtk[32];
    2329                 :            : 
    2330 [ -  + ][ #  # ]:          9 :         SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
    2331                 :            : 
    2332                 :          9 :         sm->GTimeoutCtr++;
    2333         [ -  + ]:          9 :         if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) {
    2334                 :            :                 /* No point in sending the EAPOL-Key - we will disconnect
    2335                 :            :                  * immediately following this. */
    2336                 :          0 :                 return;
    2337                 :            :         }
    2338                 :            : 
    2339         [ +  + ]:          9 :         if (sm->wpa == WPA_VERSION_WPA)
    2340                 :          8 :                 sm->PInitAKeys = FALSE;
    2341                 :          9 :         sm->TimeoutEvt = FALSE;
    2342                 :            :         /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */
    2343                 :          9 :         os_memset(rsc, 0, WPA_KEY_RSC_LEN);
    2344         [ +  - ]:          9 :         if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE)
    2345                 :          9 :                 wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc);
    2346                 :          9 :         wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2347                 :            :                         "sending 1/2 msg of Group Key Handshake");
    2348                 :            : 
    2349                 :          9 :         gtk = gsm->GTK[gsm->GN - 1];
    2350         [ -  + ]:          9 :         if (sm->wpa_auth->conf.disable_gtk) {
    2351                 :            :                 /*
    2352                 :            :                  * Provide unique random GTK to each STA to prevent use
    2353                 :            :                  * of GTK in the BSS.
    2354                 :            :                  */
    2355         [ #  # ]:          0 :                 if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0)
    2356                 :          0 :                         return;
    2357                 :          0 :                 gtk = dummy_gtk;
    2358                 :            :         }
    2359         [ +  + ]:          9 :         if (sm->wpa == WPA_VERSION_WPA2) {
    2360                 :          2 :                 kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
    2361                 :          1 :                         ieee80211w_kde_len(sm);
    2362                 :          1 :                 kde = os_malloc(kde_len);
    2363         [ -  + ]:          1 :                 if (kde == NULL)
    2364                 :          0 :                         return;
    2365                 :            : 
    2366                 :          1 :                 pos = kde;
    2367                 :          1 :                 hdr[0] = gsm->GN & 0x03;
    2368                 :          1 :                 hdr[1] = 0;
    2369                 :          1 :                 pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
    2370                 :          1 :                                   gtk, gsm->GTK_len);
    2371                 :          1 :                 pos = ieee80211w_kde_add(sm, pos);
    2372                 :            :         } else {
    2373                 :          8 :                 kde = gtk;
    2374                 :          8 :                 pos = kde + gsm->GTK_len;
    2375                 :            :         }
    2376                 :            : 
    2377         [ -  + ]:          9 :         wpa_send_eapol(sm->wpa_auth, sm,
    2378                 :            :                        WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
    2379                 :            :                        WPA_KEY_INFO_ACK |
    2380                 :          9 :                        (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0),
    2381                 :         18 :                        rsc, gsm->GNonce, kde, pos - kde, gsm->GN, 1);
    2382         [ +  + ]:          9 :         if (sm->wpa == WPA_VERSION_WPA2)
    2383                 :          9 :                 os_free(kde);
    2384                 :            : }
    2385                 :            : 
    2386                 :            : 
    2387                 :          9 : SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
    2388                 :            : {
    2389 [ -  + ][ #  # ]:          9 :         SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group);
    2390                 :          9 :         sm->EAPOLKeyReceived = FALSE;
    2391         [ +  + ]:          9 :         if (sm->GUpdateStationKeys)
    2392                 :          1 :                 sm->group->GKeyDoneStations--;
    2393                 :          9 :         sm->GUpdateStationKeys = FALSE;
    2394                 :          9 :         sm->GTimeoutCtr = 0;
    2395                 :            :         /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */
    2396         [ +  + ]:          9 :         wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
    2397                 :            :                          "group key handshake completed (%s)",
    2398                 :          9 :                          sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
    2399                 :          9 :         sm->has_GTK = TRUE;
    2400                 :          9 : }
    2401                 :            : 
    2402                 :            : 
    2403                 :          0 : SM_STATE(WPA_PTK_GROUP, KEYERROR)
    2404                 :            : {
    2405 [ #  # ][ #  # ]:          0 :         SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group);
    2406         [ #  # ]:          0 :         if (sm->GUpdateStationKeys)
    2407                 :          0 :                 sm->group->GKeyDoneStations--;
    2408                 :          0 :         sm->GUpdateStationKeys = FALSE;
    2409                 :          0 :         sm->Disconnect = TRUE;
    2410                 :          0 : }
    2411                 :            : 
    2412                 :            : 
    2413                 :       9832 : SM_STEP(WPA_PTK_GROUP)
    2414                 :            : {
    2415 [ +  + ][ -  + ]:       9832 :         if (sm->Init || sm->PtkGroupInit) {
    2416                 :        398 :                 SM_ENTER(WPA_PTK_GROUP, IDLE);
    2417                 :        398 :                 sm->PtkGroupInit = FALSE;
    2418   [ +  +  -  +  :       9434 :         } else switch (sm->wpa_ptk_group_state) {
                      - ]
    2419                 :            :         case WPA_PTK_GROUP_IDLE:
    2420 [ +  + ][ +  + ]:       9405 :                 if (sm->GUpdateStationKeys ||
    2421         [ +  + ]:        161 :                     (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys))
    2422                 :          9 :                         SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
    2423                 :       9405 :                 break;
    2424                 :            :         case WPA_PTK_GROUP_REKEYNEGOTIATING:
    2425 [ +  + ][ +  - ]:         20 :                 if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
                 [ +  - ]
    2426         [ +  - ]:          9 :                     !sm->EAPOLKeyPairwise && sm->MICVerified)
    2427                 :          9 :                         SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED);
    2428         [ -  + ]:         11 :                 else if (sm->GTimeoutCtr >
    2429                 :         11 :                          (int) dot11RSNAConfigGroupUpdateCount)
    2430                 :          0 :                         SM_ENTER(WPA_PTK_GROUP, KEYERROR);
    2431         [ -  + ]:         11 :                 else if (sm->TimeoutEvt)
    2432                 :          0 :                         SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
    2433                 :         20 :                 break;
    2434                 :            :         case WPA_PTK_GROUP_KEYERROR:
    2435                 :          0 :                 SM_ENTER(WPA_PTK_GROUP, IDLE);
    2436                 :          0 :                 break;
    2437                 :            :         case WPA_PTK_GROUP_REKEYESTABLISHED:
    2438                 :          9 :                 SM_ENTER(WPA_PTK_GROUP, IDLE);
    2439                 :          9 :                 break;
    2440                 :            :         }
    2441                 :       9832 : }
    2442                 :            : 
    2443                 :            : 
    2444                 :        637 : static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
    2445                 :            :                           struct wpa_group *group)
    2446                 :            : {
    2447                 :        637 :         int ret = 0;
    2448                 :            : 
    2449                 :        637 :         os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
    2450                 :        637 :         inc_byte_array(group->Counter, WPA_NONCE_LEN);
    2451         [ -  + ]:        637 :         if (wpa_gmk_to_gtk(group->GMK, "Group key expansion",
    2452                 :        637 :                            wpa_auth->addr, group->GNonce,
    2453                 :       1274 :                            group->GTK[group->GN - 1], group->GTK_len) < 0)
    2454                 :          0 :                 ret = -1;
    2455                 :        637 :         wpa_hexdump_key(MSG_DEBUG, "GTK",
    2456                 :       1274 :                         group->GTK[group->GN - 1], group->GTK_len);
    2457                 :            : 
    2458                 :            : #ifdef CONFIG_IEEE80211W
    2459         [ +  + ]:        637 :         if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    2460                 :        173 :                 os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
    2461                 :        173 :                 inc_byte_array(group->Counter, WPA_NONCE_LEN);
    2462         [ -  + ]:        173 :                 if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
    2463                 :        173 :                                    wpa_auth->addr, group->GNonce,
    2464                 :        173 :                                    group->IGTK[group->GN_igtk - 4],
    2465                 :            :                                    WPA_IGTK_LEN) < 0)
    2466                 :          0 :                         ret = -1;
    2467                 :        173 :                 wpa_hexdump_key(MSG_DEBUG, "IGTK",
    2468                 :        173 :                                 group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN);
    2469                 :            :         }
    2470                 :            : #endif /* CONFIG_IEEE80211W */
    2471                 :            : 
    2472                 :        637 :         return ret;
    2473                 :            : }
    2474                 :            : 
    2475                 :            : 
    2476                 :        352 : static void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth,
    2477                 :            :                                struct wpa_group *group)
    2478                 :            : {
    2479                 :        352 :         wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
    2480                 :            :                    "GTK_INIT (VLAN-ID %d)", group->vlan_id);
    2481                 :        352 :         group->changed = FALSE; /* GInit is not cleared here; avoid loop */
    2482                 :        352 :         group->wpa_group_state = WPA_GROUP_GTK_INIT;
    2483                 :            : 
    2484                 :            :         /* GTK[0..N] = 0 */
    2485                 :        352 :         os_memset(group->GTK, 0, sizeof(group->GTK));
    2486                 :        352 :         group->GN = 1;
    2487                 :        352 :         group->GM = 2;
    2488                 :            : #ifdef CONFIG_IEEE80211W
    2489                 :        352 :         group->GN_igtk = 4;
    2490                 :        352 :         group->GM_igtk = 5;
    2491                 :            : #endif /* CONFIG_IEEE80211W */
    2492                 :            :         /* GTK[GN] = CalcGTK() */
    2493                 :        352 :         wpa_gtk_update(wpa_auth, group);
    2494                 :        352 : }
    2495                 :            : 
    2496                 :            : 
    2497                 :          1 : static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
    2498                 :            : {
    2499 [ -  + ][ #  # ]:          1 :         if (ctx != NULL && ctx != sm->group)
    2500                 :          0 :                 return 0;
    2501                 :            : 
    2502         [ -  + ]:          1 :         if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) {
    2503                 :          0 :                 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2504                 :            :                                 "Not in PTKINITDONE; skip Group Key update");
    2505                 :          0 :                 sm->GUpdateStationKeys = FALSE;
    2506                 :          0 :                 return 0;
    2507                 :            :         }
    2508         [ -  + ]:          1 :         if (sm->GUpdateStationKeys) {
    2509                 :            :                 /*
    2510                 :            :                  * This should not really happen, so add a debug log entry.
    2511                 :            :                  * Since we clear the GKeyDoneStations before the loop, the
    2512                 :            :                  * station needs to be counted here anyway.
    2513                 :            :                  */
    2514                 :          0 :                 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
    2515                 :            :                                 "GUpdateStationKeys was already set when "
    2516                 :            :                                 "marking station for GTK rekeying");
    2517                 :            :         }
    2518                 :            : 
    2519                 :            :         /* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */
    2520         [ -  + ]:          1 :         if (sm->is_wnmsleep)
    2521                 :          0 :                 return 0;
    2522                 :            : 
    2523                 :          1 :         sm->group->GKeyDoneStations++;
    2524                 :          1 :         sm->GUpdateStationKeys = TRUE;
    2525                 :            : 
    2526                 :          1 :         wpa_sm_step(sm);
    2527                 :          1 :         return 0;
    2528                 :            : }
    2529                 :            : 
    2530                 :            : 
    2531                 :            : #ifdef CONFIG_WNM
    2532                 :            : /* update GTK when exiting WNM-Sleep Mode */
    2533                 :          2 : void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm)
    2534                 :            : {
    2535 [ +  + ][ -  + ]:          2 :         if (sm == NULL || sm->is_wnmsleep)
    2536                 :          2 :                 return;
    2537                 :            : 
    2538                 :          1 :         wpa_group_update_sta(sm, NULL);
    2539                 :            : }
    2540                 :            : 
    2541                 :            : 
    2542                 :          6 : void wpa_set_wnmsleep(struct wpa_state_machine *sm, int flag)
    2543                 :            : {
    2544         [ +  + ]:          6 :         if (sm)
    2545                 :          4 :                 sm->is_wnmsleep = !!flag;
    2546                 :          6 : }
    2547                 :            : 
    2548                 :            : 
    2549                 :          1 : int wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos)
    2550                 :            : {
    2551                 :          1 :         struct wpa_group *gsm = sm->group;
    2552                 :          1 :         u8 *start = pos;
    2553                 :            : 
    2554                 :            :         /*
    2555                 :            :          * GTK subelement:
    2556                 :            :          * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
    2557                 :            :          * Key[5..32]
    2558                 :            :          */
    2559                 :          1 :         *pos++ = WNM_SLEEP_SUBELEM_GTK;
    2560                 :          1 :         *pos++ = 11 + gsm->GTK_len;
    2561                 :            :         /* Key ID in B0-B1 of Key Info */
    2562                 :          1 :         WPA_PUT_LE16(pos, gsm->GN & 0x03);
    2563                 :          1 :         pos += 2;
    2564                 :          1 :         *pos++ = gsm->GTK_len;
    2565         [ -  + ]:          1 :         if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0)
    2566                 :          0 :                 return 0;
    2567                 :          1 :         pos += 8;
    2568                 :          1 :         os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len);
    2569                 :          1 :         pos += gsm->GTK_len;
    2570                 :            : 
    2571                 :          1 :         wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit",
    2572                 :            :                    gsm->GN);
    2573                 :          1 :         wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit",
    2574                 :          2 :                         gsm->GTK[gsm->GN - 1], gsm->GTK_len);
    2575                 :            : 
    2576                 :          1 :         return pos - start;
    2577                 :            : }
    2578                 :            : 
    2579                 :            : 
    2580                 :            : #ifdef CONFIG_IEEE80211W
    2581                 :          1 : int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos)
    2582                 :            : {
    2583                 :          1 :         struct wpa_group *gsm = sm->group;
    2584                 :          1 :         u8 *start = pos;
    2585                 :            : 
    2586                 :            :         /*
    2587                 :            :          * IGTK subelement:
    2588                 :            :          * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16]
    2589                 :            :          */
    2590                 :          1 :         *pos++ = WNM_SLEEP_SUBELEM_IGTK;
    2591                 :          1 :         *pos++ = 2 + 6 + WPA_IGTK_LEN;
    2592                 :          1 :         WPA_PUT_LE16(pos, gsm->GN_igtk);
    2593                 :          1 :         pos += 2;
    2594         [ -  + ]:          1 :         if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0)
    2595                 :          0 :                 return 0;
    2596                 :          1 :         pos += 6;
    2597                 :            : 
    2598                 :          1 :         os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
    2599                 :          1 :         pos += WPA_IGTK_LEN;
    2600                 :            : 
    2601                 :          1 :         wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit",
    2602                 :            :                    gsm->GN_igtk);
    2603                 :          1 :         wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit",
    2604                 :          1 :                         gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
    2605                 :            : 
    2606                 :          1 :         return pos - start;
    2607                 :            : }
    2608                 :            : #endif /* CONFIG_IEEE80211W */
    2609                 :            : #endif /* CONFIG_WNM */
    2610                 :            : 
    2611                 :            : 
    2612                 :          0 : static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,
    2613                 :            :                               struct wpa_group *group)
    2614                 :            : {
    2615                 :            :         int tmp;
    2616                 :            : 
    2617                 :          0 :         wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
    2618                 :            :                    "SETKEYS (VLAN-ID %d)", group->vlan_id);
    2619                 :          0 :         group->changed = TRUE;
    2620                 :          0 :         group->wpa_group_state = WPA_GROUP_SETKEYS;
    2621                 :          0 :         group->GTKReKey = FALSE;
    2622                 :          0 :         tmp = group->GM;
    2623                 :          0 :         group->GM = group->GN;
    2624                 :          0 :         group->GN = tmp;
    2625                 :            : #ifdef CONFIG_IEEE80211W
    2626                 :          0 :         tmp = group->GM_igtk;
    2627                 :          0 :         group->GM_igtk = group->GN_igtk;
    2628                 :          0 :         group->GN_igtk = tmp;
    2629                 :            : #endif /* CONFIG_IEEE80211W */
    2630                 :            :         /* "GKeyDoneStations = GNoStations" is done in more robust way by
    2631                 :            :          * counting the STAs that are marked with GUpdateStationKeys instead of
    2632                 :            :          * including all STAs that could be in not-yet-completed state. */
    2633                 :          0 :         wpa_gtk_update(wpa_auth, group);
    2634                 :            : 
    2635         [ #  # ]:          0 :         if (group->GKeyDoneStations) {
    2636                 :          0 :                 wpa_printf(MSG_DEBUG, "wpa_group_setkeys: Unexpected "
    2637                 :            :                            "GKeyDoneStations=%d when starting new GTK rekey",
    2638                 :            :                            group->GKeyDoneStations);
    2639                 :          0 :                 group->GKeyDoneStations = 0;
    2640                 :            :         }
    2641                 :          0 :         wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, group);
    2642                 :          0 :         wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d",
    2643                 :            :                    group->GKeyDoneStations);
    2644                 :          0 : }
    2645                 :            : 
    2646                 :            : 
    2647                 :        637 : static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
    2648                 :            :                                        struct wpa_group *group)
    2649                 :            : {
    2650                 :        637 :         int ret = 0;
    2651                 :            : 
    2652         [ -  + ]:        637 :         if (wpa_auth_set_key(wpa_auth, group->vlan_id,
    2653                 :        637 :                              wpa_cipher_to_alg(wpa_auth->conf.wpa_group),
    2654                 :            :                              broadcast_ether_addr, group->GN,
    2655                 :       1274 :                              group->GTK[group->GN - 1], group->GTK_len) < 0)
    2656                 :          0 :                 ret = -1;
    2657                 :            : 
    2658                 :            : #ifdef CONFIG_IEEE80211W
    2659   [ +  +  -  + ]:        810 :         if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION &&
    2660                 :        173 :             wpa_auth_set_key(wpa_auth, group->vlan_id, WPA_ALG_IGTK,
    2661                 :            :                              broadcast_ether_addr, group->GN_igtk,
    2662                 :        173 :                              group->IGTK[group->GN_igtk - 4],
    2663                 :            :                              WPA_IGTK_LEN) < 0)
    2664                 :          0 :                 ret = -1;
    2665                 :            : #endif /* CONFIG_IEEE80211W */
    2666                 :            : 
    2667                 :        637 :         return ret;
    2668                 :            : }
    2669                 :            : 
    2670                 :            : 
    2671                 :          0 : static int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx)
    2672                 :            : {
    2673         [ #  # ]:          0 :         if (sm->group == ctx) {
    2674                 :          0 :                 wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR
    2675                 :            :                            " for discconnection due to fatal failure",
    2676                 :          0 :                            MAC2STR(sm->addr));
    2677                 :          0 :                 sm->Disconnect = TRUE;
    2678                 :            :         }
    2679                 :            : 
    2680                 :          0 :         return 0;
    2681                 :            : }
    2682                 :            : 
    2683                 :            : 
    2684                 :          0 : static void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth,
    2685                 :            :                                     struct wpa_group *group)
    2686                 :            : {
    2687                 :          0 :         wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE");
    2688                 :          0 :         group->changed = TRUE;
    2689                 :          0 :         group->wpa_group_state = WPA_GROUP_FATAL_FAILURE;
    2690                 :          0 :         wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group);
    2691                 :          0 : }
    2692                 :            : 
    2693                 :            : 
    2694                 :        352 : static int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth,
    2695                 :            :                                  struct wpa_group *group)
    2696                 :            : {
    2697                 :        352 :         wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
    2698                 :            :                    "SETKEYSDONE (VLAN-ID %d)", group->vlan_id);
    2699                 :        352 :         group->changed = TRUE;
    2700                 :        352 :         group->wpa_group_state = WPA_GROUP_SETKEYSDONE;
    2701                 :            : 
    2702         [ -  + ]:        352 :         if (wpa_group_config_group_keys(wpa_auth, group) < 0) {
    2703                 :          0 :                 wpa_group_fatal_failure(wpa_auth, group);
    2704                 :          0 :                 return -1;
    2705                 :            :         }
    2706                 :            : 
    2707                 :        352 :         return 0;
    2708                 :            : }
    2709                 :            : 
    2710                 :            : 
    2711                 :      10536 : static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
    2712                 :            :                               struct wpa_group *group)
    2713                 :            : {
    2714         [ +  + ]:      10536 :         if (group->GInit) {
    2715                 :        352 :                 wpa_group_gtk_init(wpa_auth, group);
    2716         [ +  - ]:      10184 :         } else if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) {
    2717                 :            :                 /* Do not allow group operations */
    2718 [ +  + ][ +  - ]:      10184 :         } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT &&
    2719                 :        352 :                    group->GTKAuthenticator) {
    2720                 :        352 :                 wpa_group_setkeysdone(wpa_auth, group);
    2721 [ +  - ][ -  + ]:       9832 :         } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE &&
    2722                 :       9832 :                    group->GTKReKey) {
    2723                 :          0 :                 wpa_group_setkeys(wpa_auth, group);
    2724         [ -  + ]:       9832 :         } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) {
    2725         [ #  # ]:          0 :                 if (group->GKeyDoneStations == 0)
    2726                 :          0 :                         wpa_group_setkeysdone(wpa_auth, group);
    2727         [ #  # ]:          0 :                 else if (group->GTKReKey)
    2728                 :          0 :                         wpa_group_setkeys(wpa_auth, group);
    2729                 :            :         }
    2730                 :      10536 : }
    2731                 :            : 
    2732                 :            : 
    2733                 :       5797 : static int wpa_sm_step(struct wpa_state_machine *sm)
    2734                 :            : {
    2735         [ -  + ]:       5797 :         if (sm == NULL)
    2736                 :          0 :                 return 0;
    2737                 :            : 
    2738         [ +  + ]:       5797 :         if (sm->in_step_loop) {
    2739                 :            :                 /* This should not happen, but if it does, make sure we do not
    2740                 :            :                  * end up freeing the state machine too early by exiting the
    2741                 :            :                  * recursive call. */
    2742                 :          7 :                 wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively");
    2743                 :          7 :                 return 0;
    2744                 :            :         }
    2745                 :            : 
    2746                 :       5790 :         sm->in_step_loop = 1;
    2747                 :            :         do {
    2748         [ -  + ]:       9832 :                 if (sm->pending_deinit)
    2749                 :          0 :                         break;
    2750                 :            : 
    2751                 :       9832 :                 sm->changed = FALSE;
    2752                 :       9832 :                 sm->wpa_auth->group->changed = FALSE;
    2753                 :            : 
    2754                 :       9832 :                 SM_STEP_RUN(WPA_PTK);
    2755         [ -  + ]:       9832 :                 if (sm->pending_deinit)
    2756                 :          0 :                         break;
    2757                 :       9832 :                 SM_STEP_RUN(WPA_PTK_GROUP);
    2758         [ -  + ]:       9832 :                 if (sm->pending_deinit)
    2759                 :          0 :                         break;
    2760                 :       9832 :                 wpa_group_sm_step(sm->wpa_auth, sm->group);
    2761 [ -  + ][ +  + ]:       9832 :         } while (sm->changed || sm->wpa_auth->group->changed);
    2762                 :       5790 :         sm->in_step_loop = 0;
    2763                 :            : 
    2764         [ -  + ]:       5790 :         if (sm->pending_deinit) {
    2765                 :          0 :                 wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state "
    2766                 :          0 :                            "machine deinit for " MACSTR, MAC2STR(sm->addr));
    2767                 :          0 :                 wpa_free_sta_sm(sm);
    2768                 :          0 :                 return 1;
    2769                 :            :         }
    2770                 :       5797 :         return 0;
    2771                 :            : }
    2772                 :            : 
    2773                 :            : 
    2774                 :       3312 : static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx)
    2775                 :            : {
    2776                 :       3312 :         struct wpa_state_machine *sm = eloop_ctx;
    2777                 :       3312 :         wpa_sm_step(sm);
    2778                 :       3312 : }
    2779                 :            : 
    2780                 :            : 
    2781                 :       4602 : void wpa_auth_sm_notify(struct wpa_state_machine *sm)
    2782                 :            : {
    2783         [ +  + ]:       4602 :         if (sm == NULL)
    2784                 :       4602 :                 return;
    2785                 :       3326 :         eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
    2786                 :            : }
    2787                 :            : 
    2788                 :            : 
    2789                 :          0 : void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth)
    2790                 :            : {
    2791                 :            :         int tmp, i;
    2792                 :            :         struct wpa_group *group;
    2793                 :            : 
    2794         [ #  # ]:          0 :         if (wpa_auth == NULL)
    2795                 :          0 :                 return;
    2796                 :            : 
    2797                 :          0 :         group = wpa_auth->group;
    2798                 :            : 
    2799         [ #  # ]:          0 :         for (i = 0; i < 2; i++) {
    2800                 :          0 :                 tmp = group->GM;
    2801                 :          0 :                 group->GM = group->GN;
    2802                 :          0 :                 group->GN = tmp;
    2803                 :            : #ifdef CONFIG_IEEE80211W
    2804                 :          0 :                 tmp = group->GM_igtk;
    2805                 :          0 :                 group->GM_igtk = group->GN_igtk;
    2806                 :          0 :                 group->GN_igtk = tmp;
    2807                 :            : #endif /* CONFIG_IEEE80211W */
    2808                 :          0 :                 wpa_gtk_update(wpa_auth, group);
    2809                 :          0 :                 wpa_group_config_group_keys(wpa_auth, group);
    2810                 :            :         }
    2811                 :            : }
    2812                 :            : 
    2813                 :            : 
    2814                 :          9 : static const char * wpa_bool_txt(int bool)
    2815                 :            : {
    2816         [ +  + ]:          9 :         return bool ? "TRUE" : "FALSE";
    2817                 :            : }
    2818                 :            : 
    2819                 :            : 
    2820                 :            : #define RSN_SUITE "%02x-%02x-%02x-%d"
    2821                 :            : #define RSN_SUITE_ARG(s) \
    2822                 :            : ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
    2823                 :            : 
    2824                 :          3 : int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
    2825                 :            : {
    2826                 :          3 :         int len = 0, ret;
    2827                 :            :         char pmkid_txt[PMKID_LEN * 2 + 1];
    2828                 :            : #ifdef CONFIG_RSN_PREAUTH
    2829                 :          3 :         const int preauth = 1;
    2830                 :            : #else /* CONFIG_RSN_PREAUTH */
    2831                 :          0 :         const int preauth = 0;
    2832                 :            : #endif /* CONFIG_RSN_PREAUTH */
    2833                 :            : 
    2834         [ -  + ]:          3 :         if (wpa_auth == NULL)
    2835                 :          0 :                 return len;
    2836                 :            : 
    2837                 :          3 :         ret = os_snprintf(buf + len, buflen - len,
    2838                 :            :                           "dot11RSNAOptionImplemented=TRUE\n"
    2839                 :            :                           "dot11RSNAPreauthenticationImplemented=%s\n"
    2840                 :            :                           "dot11RSNAEnabled=%s\n"
    2841                 :            :                           "dot11RSNAPreauthenticationEnabled=%s\n",
    2842                 :            :                           wpa_bool_txt(preauth),
    2843                 :          3 :                           wpa_bool_txt(wpa_auth->conf.wpa & WPA_PROTO_RSN),
    2844                 :            :                           wpa_bool_txt(wpa_auth->conf.rsn_preauth));
    2845 [ -  + ][ +  - ]:          3 :         if (ret < 0 || (size_t) ret >= buflen - len)
    2846                 :          0 :                 return len;
    2847                 :          3 :         len += ret;
    2848                 :            : 
    2849                 :          3 :         wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
    2850                 :          3 :                          wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN);
    2851                 :            : 
    2852                 :         84 :         ret = os_snprintf(
    2853                 :          3 :                 buf + len, buflen - len,
    2854                 :            :                 "dot11RSNAConfigVersion=%u\n"
    2855                 :            :                 "dot11RSNAConfigPairwiseKeysSupported=9999\n"
    2856                 :            :                 /* FIX: dot11RSNAConfigGroupCipher */
    2857                 :            :                 /* FIX: dot11RSNAConfigGroupRekeyMethod */
    2858                 :            :                 /* FIX: dot11RSNAConfigGroupRekeyTime */
    2859                 :            :                 /* FIX: dot11RSNAConfigGroupRekeyPackets */
    2860                 :            :                 "dot11RSNAConfigGroupRekeyStrict=%u\n"
    2861                 :            :                 "dot11RSNAConfigGroupUpdateCount=%u\n"
    2862                 :            :                 "dot11RSNAConfigPairwiseUpdateCount=%u\n"
    2863                 :            :                 "dot11RSNAConfigGroupCipherSize=%u\n"
    2864                 :            :                 "dot11RSNAConfigPMKLifetime=%u\n"
    2865                 :            :                 "dot11RSNAConfigPMKReauthThreshold=%u\n"
    2866                 :            :                 "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n"
    2867                 :            :                 "dot11RSNAConfigSATimeout=%u\n"
    2868                 :            :                 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
    2869                 :            :                 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
    2870                 :            :                 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
    2871                 :            :                 "dot11RSNAPMKIDUsed=%s\n"
    2872                 :            :                 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
    2873                 :            :                 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
    2874                 :            :                 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
    2875                 :            :                 "dot11RSNATKIPCounterMeasuresInvoked=%u\n"
    2876                 :            :                 "dot11RSNA4WayHandshakeFailures=%u\n"
    2877                 :            :                 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n",
    2878                 :            :                 RSN_VERSION,
    2879                 :          3 :                 !!wpa_auth->conf.wpa_strict_rekey,
    2880                 :            :                 dot11RSNAConfigGroupUpdateCount,
    2881                 :            :                 dot11RSNAConfigPairwiseUpdateCount,
    2882                 :          3 :                 wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8,
    2883                 :            :                 dot11RSNAConfigPMKLifetime,
    2884                 :            :                 dot11RSNAConfigPMKReauthThreshold,
    2885                 :            :                 dot11RSNAConfigSATimeout,
    2886                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteSelected),
    2887                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherSelected),
    2888                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected),
    2889                 :            :                 pmkid_txt,
    2890                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAAuthenticationSuiteRequested),
    2891                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAPairwiseCipherRequested),
    2892                 :         12 :                 RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested),
    2893                 :            :                 wpa_auth->dot11RSNATKIPCounterMeasuresInvoked,
    2894                 :            :                 wpa_auth->dot11RSNA4WayHandshakeFailures);
    2895 [ -  + ][ +  - ]:          3 :         if (ret < 0 || (size_t) ret >= buflen - len)
    2896                 :          0 :                 return len;
    2897                 :          3 :         len += ret;
    2898                 :            : 
    2899                 :            :         /* TODO: dot11RSNAConfigPairwiseCiphersTable */
    2900                 :            :         /* TODO: dot11RSNAConfigAuthenticationSuitesTable */
    2901                 :            : 
    2902                 :            :         /* Private MIB */
    2903                 :          3 :         ret = os_snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n",
    2904                 :          3 :                           wpa_auth->group->wpa_group_state);
    2905 [ +  - ][ -  + ]:          3 :         if (ret < 0 || (size_t) ret >= buflen - len)
    2906                 :          0 :                 return len;
    2907                 :          3 :         len += ret;
    2908                 :            : 
    2909                 :          3 :         return len;
    2910                 :            : }
    2911                 :            : 
    2912                 :            : 
    2913                 :         19 : int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen)
    2914                 :            : {
    2915                 :         19 :         int len = 0, ret;
    2916                 :         19 :         u32 pairwise = 0;
    2917                 :            : 
    2918         [ +  + ]:         19 :         if (sm == NULL)
    2919                 :          8 :                 return 0;
    2920                 :            : 
    2921                 :            :         /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */
    2922                 :            : 
    2923                 :            :         /* dot11RSNAStatsEntry */
    2924                 :            : 
    2925         [ +  - ]:         11 :         pairwise = wpa_cipher_to_suite(sm->wpa == WPA_VERSION_WPA2 ?
    2926                 :            :                                        WPA_PROTO_RSN : WPA_PROTO_WPA,
    2927                 :            :                                        sm->pairwise);
    2928         [ -  + ]:         11 :         if (pairwise == 0)
    2929                 :          0 :                 return 0;
    2930                 :            : 
    2931                 :        110 :         ret = os_snprintf(
    2932                 :         11 :                 buf + len, buflen - len,
    2933                 :            :                 /* TODO: dot11RSNAStatsIndex */
    2934                 :            :                 "dot11RSNAStatsSTAAddress=" MACSTR "\n"
    2935                 :            :                 "dot11RSNAStatsVersion=1\n"
    2936                 :            :                 "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n"
    2937                 :            :                 /* TODO: dot11RSNAStatsTKIPICVErrors */
    2938                 :            :                 "dot11RSNAStatsTKIPLocalMICFailures=%u\n"
    2939                 :            :                 "dot11RSNAStatsTKIPRemoteMICFailures=%u\n"
    2940                 :            :                 /* TODO: dot11RSNAStatsCCMPReplays */
    2941                 :            :                 /* TODO: dot11RSNAStatsCCMPDecryptErrors */
    2942                 :            :                 /* TODO: dot11RSNAStatsTKIPReplays */,
    2943                 :         66 :                 MAC2STR(sm->addr),
    2944                 :         22 :                 RSN_SUITE_ARG(pairwise),
    2945                 :            :                 sm->dot11RSNAStatsTKIPLocalMICFailures,
    2946                 :            :                 sm->dot11RSNAStatsTKIPRemoteMICFailures);
    2947 [ +  - ][ -  + ]:         11 :         if (ret < 0 || (size_t) ret >= buflen - len)
    2948                 :          0 :                 return len;
    2949                 :         11 :         len += ret;
    2950                 :            : 
    2951                 :            :         /* Private MIB */
    2952                 :         11 :         ret = os_snprintf(buf + len, buflen - len,
    2953                 :            :                           "hostapdWPAPTKState=%d\n"
    2954                 :            :                           "hostapdWPAPTKGroupState=%d\n",
    2955                 :         11 :                           sm->wpa_ptk_state,
    2956                 :         11 :                           sm->wpa_ptk_group_state);
    2957 [ +  - ][ -  + ]:         11 :         if (ret < 0 || (size_t) ret >= buflen - len)
    2958                 :          0 :                 return len;
    2959                 :         11 :         len += ret;
    2960                 :            : 
    2961                 :         19 :         return len;
    2962                 :            : }
    2963                 :            : 
    2964                 :            : 
    2965                 :          0 : void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth)
    2966                 :            : {
    2967         [ #  # ]:          0 :         if (wpa_auth)
    2968                 :          0 :                 wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++;
    2969                 :          0 : }
    2970                 :            : 
    2971                 :            : 
    2972                 :       2263 : int wpa_auth_pairwise_set(struct wpa_state_machine *sm)
    2973                 :            : {
    2974 [ +  + ][ +  + ]:       2263 :         return sm && sm->pairwise_set;
    2975                 :            : }
    2976                 :            : 
    2977                 :            : 
    2978                 :        418 : int wpa_auth_get_pairwise(struct wpa_state_machine *sm)
    2979                 :            : {
    2980                 :        418 :         return sm->pairwise;
    2981                 :            : }
    2982                 :            : 
    2983                 :            : 
    2984                 :       2273 : int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm)
    2985                 :            : {
    2986         [ +  + ]:       2273 :         if (sm == NULL)
    2987                 :        959 :                 return -1;
    2988                 :       2273 :         return sm->wpa_key_mgmt;
    2989                 :            : }
    2990                 :            : 
    2991                 :            : 
    2992                 :          0 : int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm)
    2993                 :            : {
    2994         [ #  # ]:          0 :         if (sm == NULL)
    2995                 :          0 :                 return 0;
    2996                 :          0 :         return sm->wpa;
    2997                 :            : }
    2998                 :            : 
    2999                 :            : 
    3000                 :          0 : int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
    3001                 :            :                              struct rsn_pmksa_cache_entry *entry)
    3002                 :            : {
    3003 [ #  # ][ #  # ]:          0 :         if (sm == NULL || sm->pmksa != entry)
    3004                 :          0 :                 return -1;
    3005                 :          0 :         sm->pmksa = NULL;
    3006                 :          0 :         return 0;
    3007                 :            : }
    3008                 :            : 
    3009                 :            : 
    3010                 :            : struct rsn_pmksa_cache_entry *
    3011                 :        539 : wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm)
    3012                 :            : {
    3013         [ +  + ]:        539 :         return sm ? sm->pmksa : NULL;
    3014                 :            : }
    3015                 :            : 
    3016                 :            : 
    3017                 :          0 : void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm)
    3018                 :            : {
    3019         [ #  # ]:          0 :         if (sm)
    3020                 :          0 :                 sm->dot11RSNAStatsTKIPLocalMICFailures++;
    3021                 :          0 : }
    3022                 :            : 
    3023                 :            : 
    3024                 :       2595 : const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len)
    3025                 :            : {
    3026         [ +  + ]:       2595 :         if (wpa_auth == NULL)
    3027                 :        581 :                 return NULL;
    3028                 :       2014 :         *len = wpa_auth->wpa_ie_len;
    3029                 :       2595 :         return wpa_auth->wpa_ie;
    3030                 :            : }
    3031                 :            : 
    3032                 :            : 
    3033                 :        179 : int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
    3034                 :            :                        int session_timeout, struct eapol_state_machine *eapol)
    3035                 :            : {
    3036 [ +  + ][ +  + ]:        179 :         if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 ||
                 [ +  + ]
    3037                 :        173 :             sm->wpa_auth->conf.disable_pmksa_caching)
    3038                 :          7 :                 return -1;
    3039                 :            : 
    3040         [ +  - ]:        172 :         if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN,
    3041                 :        172 :                                  sm->wpa_auth->addr, sm->addr, session_timeout,
    3042                 :            :                                  eapol, sm->wpa_key_mgmt))
    3043                 :        172 :                 return 0;
    3044                 :            : 
    3045                 :        179 :         return -1;
    3046                 :            : }
    3047                 :            : 
    3048                 :            : 
    3049                 :          0 : int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
    3050                 :            :                                const u8 *pmk, size_t len, const u8 *sta_addr,
    3051                 :            :                                int session_timeout,
    3052                 :            :                                struct eapol_state_machine *eapol)
    3053                 :            : {
    3054         [ #  # ]:          0 :         if (wpa_auth == NULL)
    3055                 :          0 :                 return -1;
    3056                 :            : 
    3057         [ #  # ]:          0 :         if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr,
    3058                 :            :                                  sta_addr, session_timeout, eapol,
    3059                 :            :                                  WPA_KEY_MGMT_IEEE8021X))
    3060                 :          0 :                 return 0;
    3061                 :            : 
    3062                 :          0 :         return -1;
    3063                 :            : }
    3064                 :            : 
    3065                 :            : 
    3066                 :          6 : void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
    3067                 :            :                            const u8 *sta_addr)
    3068                 :            : {
    3069                 :            :         struct rsn_pmksa_cache_entry *pmksa;
    3070                 :            : 
    3071 [ +  + ][ -  + ]:          6 :         if (wpa_auth == NULL || wpa_auth->pmksa == NULL)
    3072                 :          6 :                 return;
    3073                 :          5 :         pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sta_addr, NULL);
    3074         [ +  + ]:          5 :         if (pmksa) {
    3075                 :          4 :                 wpa_printf(MSG_DEBUG, "WPA: Remove PMKSA cache entry for "
    3076                 :         24 :                            MACSTR " based on request", MAC2STR(sta_addr));
    3077                 :          4 :                 pmksa_cache_free_entry(wpa_auth->pmksa, pmksa);
    3078                 :            :         }
    3079                 :            : }
    3080                 :            : 
    3081                 :            : 
    3082                 :            : static struct wpa_group *
    3083                 :          0 : wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id)
    3084                 :            : {
    3085                 :            :         struct wpa_group *group;
    3086                 :            : 
    3087 [ #  # ][ #  # ]:          0 :         if (wpa_auth == NULL || wpa_auth->group == NULL)
    3088                 :          0 :                 return NULL;
    3089                 :            : 
    3090                 :          0 :         wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d",
    3091                 :            :                    vlan_id);
    3092                 :          0 :         group = wpa_group_init(wpa_auth, vlan_id, 0);
    3093         [ #  # ]:          0 :         if (group == NULL)
    3094                 :          0 :                 return NULL;
    3095                 :            : 
    3096                 :          0 :         group->next = wpa_auth->group->next;
    3097                 :          0 :         wpa_auth->group->next = group;
    3098                 :            : 
    3099                 :          0 :         return group;
    3100                 :            : }
    3101                 :            : 
    3102                 :            : 
    3103                 :          0 : int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
    3104                 :            : {
    3105                 :            :         struct wpa_group *group;
    3106                 :            : 
    3107 [ #  # ][ #  # ]:          0 :         if (sm == NULL || sm->wpa_auth == NULL)
    3108                 :          0 :                 return 0;
    3109                 :            : 
    3110                 :          0 :         group = sm->wpa_auth->group;
    3111         [ #  # ]:          0 :         while (group) {
    3112         [ #  # ]:          0 :                 if (group->vlan_id == vlan_id)
    3113                 :          0 :                         break;
    3114                 :          0 :                 group = group->next;
    3115                 :            :         }
    3116                 :            : 
    3117         [ #  # ]:          0 :         if (group == NULL) {
    3118                 :          0 :                 group = wpa_auth_add_group(sm->wpa_auth, vlan_id);
    3119         [ #  # ]:          0 :                 if (group == NULL)
    3120                 :          0 :                         return -1;
    3121                 :            :         }
    3122                 :            : 
    3123         [ #  # ]:          0 :         if (sm->group == group)
    3124                 :          0 :                 return 0;
    3125                 :            : 
    3126         [ #  # ]:          0 :         if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
    3127                 :          0 :                 return -1;
    3128                 :            : 
    3129                 :          0 :         wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state "
    3130                 :          0 :                    "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id);
    3131                 :            : 
    3132                 :          0 :         sm->group = group;
    3133                 :          0 :         return 0;
    3134                 :            : }
    3135                 :            : 
    3136                 :            : 
    3137                 :        636 : void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
    3138                 :            :                                   struct wpa_state_machine *sm, int ack)
    3139                 :            : {
    3140 [ +  - ][ -  + ]:        636 :         if (wpa_auth == NULL || sm == NULL)
    3141                 :        636 :                 return;
    3142                 :        636 :         wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key TX status for STA " MACSTR
    3143                 :       3816 :                    " ack=%d", MAC2STR(sm->addr), ack);
    3144 [ +  - ][ +  + ]:        636 :         if (sm->pending_1_of_4_timeout && ack) {
    3145                 :            :                 /*
    3146                 :            :                  * Some deployed supplicant implementations update their SNonce
    3147                 :            :                  * for each EAPOL-Key 2/4 message even within the same 4-way
    3148                 :            :                  * handshake and then fail to use the first SNonce when
    3149                 :            :                  * deriving the PTK. This results in unsuccessful 4-way
    3150                 :            :                  * handshake whenever the relatively short initial timeout is
    3151                 :            :                  * reached and EAPOL-Key 1/4 is retransmitted. Try to work
    3152                 :            :                  * around this by increasing the timeout now that we know that
    3153                 :            :                  * the station has received the frame.
    3154                 :            :                  */
    3155                 :        310 :                 int timeout_ms = eapol_key_timeout_subseq;
    3156                 :        310 :                 wpa_printf(MSG_DEBUG, "WPA: Increase initial EAPOL-Key 1/4 "
    3157                 :            :                            "timeout by %u ms because of acknowledged frame",
    3158                 :            :                            timeout_ms);
    3159                 :        310 :                 eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
    3160                 :        310 :                 eloop_register_timeout(timeout_ms / 1000,
    3161                 :        310 :                                        (timeout_ms % 1000) * 1000,
    3162                 :            :                                        wpa_send_eapol_timeout, wpa_auth, sm);
    3163                 :            :         }
    3164                 :            : }
    3165                 :            : 
    3166                 :            : 
    3167                 :        426 : int wpa_auth_uses_sae(struct wpa_state_machine *sm)
    3168                 :            : {
    3169         [ -  + ]:        426 :         if (sm == NULL)
    3170                 :          0 :                 return 0;
    3171                 :        426 :         return wpa_key_mgmt_sae(sm->wpa_key_mgmt);
    3172                 :            : }
    3173                 :            : 
    3174                 :            : 
    3175                 :          4 : int wpa_auth_uses_ft_sae(struct wpa_state_machine *sm)
    3176                 :            : {
    3177         [ -  + ]:          4 :         if (sm == NULL)
    3178                 :          0 :                 return 0;
    3179                 :          4 :         return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE;
    3180                 :            : }
    3181                 :            : 
    3182                 :            : 
    3183                 :            : #ifdef CONFIG_P2P
    3184                 :        101 : int wpa_auth_get_ip_addr(struct wpa_state_machine *sm, u8 *addr)
    3185                 :            : {
    3186 [ +  + ][ +  + ]:        101 :         if (sm == NULL || WPA_GET_BE32(sm->ip_addr) == 0)
    3187                 :         51 :                 return -1;
    3188                 :         50 :         os_memcpy(addr, sm->ip_addr, 4);
    3189                 :        101 :         return 0;
    3190                 :            : }
    3191                 :            : #endif /* CONFIG_P2P */

Generated by: LCOV version 1.9