wpa.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - WPA state machine and EAPOL-Key processing
00003  * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "crypto/aes_wrap.h"
00019 #include "crypto/crypto.h"
00020 #include "common/ieee802_11_defs.h"
00021 #include "eapol_supp/eapol_supp_sm.h"
00022 #include "wpa.h"
00023 #include "eloop.h"
00024 #include "preauth.h"
00025 #include "pmksa_cache.h"
00026 #include "wpa_i.h"
00027 #include "wpa_ie.h"
00028 #include "peerkey.h"
00029 
00030 
00042 void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
00043                         int ver, const u8 *dest, u16 proto,
00044                         u8 *msg, size_t msg_len, u8 *key_mic)
00045 {
00046         if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
00047                 /*
00048                  * Association event was not yet received; try to fetch
00049                  * BSSID from the driver.
00050                  */
00051                 if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
00052                         wpa_printf(MSG_DEBUG, "WPA: Failed to read BSSID for "
00053                                    "EAPOL-Key destination address");
00054                 } else {
00055                         dest = sm->bssid;
00056                         wpa_printf(MSG_DEBUG, "WPA: Use BSSID (" MACSTR
00057                                    ") as the destination for EAPOL-Key",
00058                                    MAC2STR(dest));
00059                 }
00060         }
00061         if (key_mic &&
00062             wpa_eapol_key_mic(kck, ver, msg, msg_len, key_mic)) {
00063                 wpa_printf(MSG_ERROR, "WPA: Failed to generate EAPOL-Key "
00064                            "version %d MIC", ver);
00065                 goto out;
00066         }
00067         wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
00068         wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
00069         eapol_sm_notify_tx_eapol_key(sm->eapol);
00070 out:
00071         os_free(msg);
00072 }
00073 
00074 
00085 void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
00086 {
00087         size_t rlen;
00088         struct wpa_eapol_key *reply;
00089         int key_info, ver;
00090         u8 bssid[ETH_ALEN], *rbuf;
00091 
00092         if (wpa_key_mgmt_ft(sm->key_mgmt) || wpa_key_mgmt_sha256(sm->key_mgmt))
00093                 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
00094         else if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
00095                 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
00096         else
00097                 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
00098 
00099         if (wpa_sm_get_bssid(sm, bssid) < 0) {
00100                 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
00101                            "request");
00102                 return;
00103         }
00104 
00105         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
00106                                   sizeof(*reply), &rlen, (void *) &reply);
00107         if (rbuf == NULL)
00108                 return;
00109 
00110         reply->type = sm->proto == WPA_PROTO_RSN ?
00111                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
00112         key_info = WPA_KEY_INFO_REQUEST | ver;
00113         if (sm->ptk_set)
00114                 key_info |= WPA_KEY_INFO_MIC;
00115         if (error)
00116                 key_info |= WPA_KEY_INFO_ERROR;
00117         if (pairwise)
00118                 key_info |= WPA_KEY_INFO_KEY_TYPE;
00119         WPA_PUT_BE16(reply->key_info, key_info);
00120         WPA_PUT_BE16(reply->key_length, 0);
00121         os_memcpy(reply->replay_counter, sm->request_counter,
00122                   WPA_REPLAY_COUNTER_LEN);
00123         inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
00124 
00125         WPA_PUT_BE16(reply->key_data_length, 0);
00126 
00127         wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d "
00128                    "pairwise=%d ptk_set=%d len=%lu)",
00129                    error, pairwise, sm->ptk_set, (unsigned long) rlen);
00130         wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
00131                            rbuf, rlen, key_info & WPA_KEY_INFO_MIC ?
00132                            reply->key_mic : NULL);
00133 }
00134 
00135 
00136 static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
00137                                   const unsigned char *src_addr,
00138                                   const u8 *pmkid)
00139 {
00140         int abort_cached = 0;
00141 
00142         if (pmkid && !sm->cur_pmksa) {
00143                 /* When using drivers that generate RSN IE, wpa_supplicant may
00144                  * not have enough time to get the association information
00145                  * event before receiving this 1/4 message, so try to find a
00146                  * matching PMKSA cache entry here. */
00147                 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid);
00148                 if (sm->cur_pmksa) {
00149                         wpa_printf(MSG_DEBUG, "RSN: found matching PMKID from "
00150                                    "PMKSA cache");
00151                 } else {
00152                         wpa_printf(MSG_DEBUG, "RSN: no matching PMKID found");
00153                         abort_cached = 1;
00154                 }
00155         }
00156 
00157         if (pmkid && sm->cur_pmksa &&
00158             os_memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
00159                 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
00160                 wpa_sm_set_pmk_from_pmksa(sm);
00161                 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
00162                                 sm->pmk, sm->pmk_len);
00163                 eapol_sm_notify_cached(sm->eapol);
00164 #ifdef CONFIG_IEEE80211R
00165                 sm->xxkey_len = 0;
00166 #endif /* CONFIG_IEEE80211R */
00167         } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
00168                 int res, pmk_len;
00169                 pmk_len = PMK_LEN;
00170                 res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
00171                 if (res) {
00172                         /*
00173                          * EAP-LEAP is an exception from other EAP methods: it
00174                          * uses only 16-byte PMK.
00175                          */
00176                         res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
00177                         pmk_len = 16;
00178                 } else {
00179 #ifdef CONFIG_IEEE80211R
00180                         u8 buf[2 * PMK_LEN];
00181                         if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
00182                         {
00183                                 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
00184                                 sm->xxkey_len = PMK_LEN;
00185                                 os_memset(buf, 0, sizeof(buf));
00186                         }
00187 #endif /* CONFIG_IEEE80211R */
00188                 }
00189                 if (res == 0) {
00190                         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
00191                                         "machines", sm->pmk, pmk_len);
00192                         sm->pmk_len = pmk_len;
00193                         if (sm->proto == WPA_PROTO_RSN) {
00194                                 pmksa_cache_add(sm->pmksa, sm->pmk, pmk_len,
00195                                                 src_addr, sm->own_addr,
00196                                                 sm->network_ctx, sm->key_mgmt);
00197                         }
00198                         if (!sm->cur_pmksa && pmkid &&
00199                             pmksa_cache_get(sm->pmksa, src_addr, pmkid)) {
00200                                 wpa_printf(MSG_DEBUG, "RSN: the new PMK "
00201                                            "matches with the PMKID");
00202                                 abort_cached = 0;
00203                         }
00204                 } else {
00205                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
00206                                 "WPA: Failed to get master session key from "
00207                                 "EAPOL state machines");
00208                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
00209                                 "WPA: Key handshake aborted");
00210                         if (sm->cur_pmksa) {
00211                                 wpa_printf(MSG_DEBUG, "RSN: Cancelled PMKSA "
00212                                            "caching attempt");
00213                                 sm->cur_pmksa = NULL;
00214                                 abort_cached = 1;
00215                         } else if (!abort_cached) {
00216                                 return -1;
00217                         }
00218                 }
00219         }
00220 
00221         if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) {
00222                 /* Send EAPOL-Start to trigger full EAP authentication. */
00223                 u8 *buf;
00224                 size_t buflen;
00225 
00226                 wpa_printf(MSG_DEBUG, "RSN: no PMKSA entry found - trigger "
00227                            "full EAP authentication");
00228                 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
00229                                          NULL, 0, &buflen, NULL);
00230                 if (buf) {
00231                         wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
00232                                           buf, buflen);
00233                         os_free(buf);
00234                 }
00235 
00236                 return -1;
00237         }
00238 
00239         return 0;
00240 }
00241 
00242 
00255 int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
00256                                const struct wpa_eapol_key *key,
00257                                int ver, const u8 *nonce,
00258                                const u8 *wpa_ie, size_t wpa_ie_len,
00259                                struct wpa_ptk *ptk)
00260 {
00261         size_t rlen;
00262         struct wpa_eapol_key *reply;
00263         u8 *rbuf;
00264         u8 *rsn_ie_buf = NULL;
00265 
00266         if (wpa_ie == NULL) {
00267                 wpa_printf(MSG_WARNING, "WPA: No wpa_ie set - cannot "
00268                            "generate msg 2/4");
00269                 return -1;
00270         }
00271 
00272 #ifdef CONFIG_IEEE80211R
00273         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
00274                 int res;
00275 
00276                 /*
00277                  * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
00278                  * FTIE from (Re)Association Response.
00279                  */
00280                 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
00281                                        sm->assoc_resp_ies_len);
00282                 if (rsn_ie_buf == NULL)
00283                         return -1;
00284                 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
00285                 res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len,
00286                                        sm->pmk_r1_name);
00287                 if (res < 0) {
00288                         os_free(rsn_ie_buf);
00289                         return -1;
00290                 }
00291                 wpa_ie_len += res;
00292 
00293                 if (sm->assoc_resp_ies) {
00294                         os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
00295                                   sm->assoc_resp_ies_len);
00296                         wpa_ie_len += sm->assoc_resp_ies_len;
00297                 }
00298 
00299                 wpa_ie = rsn_ie_buf;
00300         }
00301 #endif /* CONFIG_IEEE80211R */
00302 
00303         wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
00304 
00305         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
00306                                   NULL, sizeof(*reply) + wpa_ie_len,
00307                                   &rlen, (void *) &reply);
00308         if (rbuf == NULL) {
00309                 os_free(rsn_ie_buf);
00310                 return -1;
00311         }
00312 
00313         reply->type = sm->proto == WPA_PROTO_RSN ?
00314                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
00315         WPA_PUT_BE16(reply->key_info,
00316                      ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
00317         if (sm->proto == WPA_PROTO_RSN)
00318                 WPA_PUT_BE16(reply->key_length, 0);
00319         else
00320                 os_memcpy(reply->key_length, key->key_length, 2);
00321         os_memcpy(reply->replay_counter, key->replay_counter,
00322                   WPA_REPLAY_COUNTER_LEN);
00323 
00324         WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
00325         os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
00326         os_free(rsn_ie_buf);
00327 
00328         os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
00329 
00330         wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
00331         wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
00332                            rbuf, rlen, reply->key_mic);
00333 
00334         return 0;
00335 }
00336 
00337 
00338 static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
00339                           const struct wpa_eapol_key *key,
00340                           struct wpa_ptk *ptk)
00341 {
00342         size_t ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64;
00343 #ifdef CONFIG_IEEE80211R
00344         if (wpa_key_mgmt_ft(sm->key_mgmt))
00345                 return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len);
00346 #endif /* CONFIG_IEEE80211R */
00347 
00348         wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
00349                        sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
00350                        (u8 *) ptk, ptk_len,
00351                        wpa_key_mgmt_sha256(sm->key_mgmt));
00352         return 0;
00353 }
00354 
00355 
00356 static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
00357                                           const unsigned char *src_addr,
00358                                           const struct wpa_eapol_key *key,
00359                                           u16 ver)
00360 {
00361         struct wpa_eapol_ie_parse ie;
00362         struct wpa_ptk *ptk;
00363         u8 buf[8];
00364 
00365         if (wpa_sm_get_network_ctx(sm) == NULL) {
00366                 wpa_printf(MSG_WARNING, "WPA: No SSID info found (msg 1 of "
00367                            "4).");
00368                 return;
00369         }
00370 
00371         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
00372         wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "
00373                    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
00374 
00375         os_memset(&ie, 0, sizeof(ie));
00376 
00377 #ifndef CONFIG_NO_WPA2
00378         if (sm->proto == WPA_PROTO_RSN) {
00379                 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
00380                 const u8 *_buf = (const u8 *) (key + 1);
00381                 size_t len = WPA_GET_BE16(key->key_data_length);
00382                 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len);
00383                 wpa_supplicant_parse_ies(_buf, len, &ie);
00384                 if (ie.pmkid) {
00385                         wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
00386                                     "Authenticator", ie.pmkid, PMKID_LEN);
00387                 }
00388         }
00389 #endif /* CONFIG_NO_WPA2 */
00390 
00391         if (wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid))
00392                 goto failed;
00393 
00394         if (sm->renew_snonce) {
00395                 if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
00396                         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
00397                                 "WPA: Failed to get random data for SNonce");
00398                         goto failed;
00399                 }
00400                 sm->renew_snonce = 0;
00401                 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
00402                             sm->snonce, WPA_NONCE_LEN);
00403         }
00404 
00405         /* Calculate PTK which will be stored as a temporary PTK until it has
00406          * been verified when processing message 3/4. */
00407         ptk = &sm->tptk;
00408         wpa_derive_ptk(sm, src_addr, key, ptk);
00409         /* Supplicant: swap tx/rx Mic keys */
00410         os_memcpy(buf, ptk->u.auth.tx_mic_key, 8);
00411         os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
00412         os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);
00413         sm->tptk_set = 1;
00414 
00415         if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
00416                                        sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,
00417                                        ptk))
00418                 goto failed;
00419 
00420         os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
00421         return;
00422 
00423 failed:
00424         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
00425 }
00426 
00427 
00428 static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
00429 {
00430         struct wpa_sm *sm = eloop_ctx;
00431         rsn_preauth_candidate_process(sm);
00432 }
00433 
00434 
00435 static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
00436                                             const u8 *addr, int secure)
00437 {
00438         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
00439                 "WPA: Key negotiation completed with "
00440                 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
00441                 wpa_cipher_txt(sm->pairwise_cipher),
00442                 wpa_cipher_txt(sm->group_cipher));
00443         wpa_sm_cancel_auth_timeout(sm);
00444         wpa_sm_set_state(sm, WPA_COMPLETED);
00445 
00446         if (secure) {
00447                 wpa_sm_mlme_setprotection(
00448                         sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
00449                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
00450                 eapol_sm_notify_portValid(sm->eapol, TRUE);
00451                 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
00452                         eapol_sm_notify_eap_success(sm->eapol, TRUE);
00453                 /*
00454                  * Start preauthentication after a short wait to avoid a
00455                  * possible race condition between the data receive and key
00456                  * configuration after the 4-Way Handshake. This increases the
00457                  * likelyhood of the first preauth EAPOL-Start frame getting to
00458                  * the target AP.
00459                  */
00460                 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
00461         }
00462 
00463         if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
00464                 wpa_printf(MSG_DEBUG, "RSN: Authenticator accepted "
00465                            "opportunistic PMKSA entry - marking it valid");
00466                 sm->cur_pmksa->opportunistic = 0;
00467         }
00468 
00469 #ifdef CONFIG_IEEE80211R
00470         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
00471                 /* Prepare for the next transition */
00472                 wpa_ft_prepare_auth_request(sm, NULL);
00473         }
00474 #endif /* CONFIG_IEEE80211R */
00475 }
00476 
00477 
00478 static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
00479 {
00480         struct wpa_sm *sm = eloop_ctx;
00481         wpa_printf(MSG_DEBUG, "WPA: Request PTK rekeying");
00482         wpa_sm_key_request(sm, 0, 1);
00483 }
00484 
00485 
00486 static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
00487                                       const struct wpa_eapol_key *key)
00488 {
00489         int keylen, rsclen;
00490         enum wpa_alg alg;
00491         const u8 *key_rsc;
00492         u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00493 
00494         wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");
00495 
00496         switch (sm->pairwise_cipher) {
00497         case WPA_CIPHER_CCMP:
00498                 alg = WPA_ALG_CCMP;
00499                 keylen = 16;
00500                 rsclen = 6;
00501                 break;
00502         case WPA_CIPHER_TKIP:
00503                 alg = WPA_ALG_TKIP;
00504                 keylen = 32;
00505                 rsclen = 6;
00506                 break;
00507         case WPA_CIPHER_NONE:
00508                 wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "
00509                            "NONE - do not use pairwise keys");
00510                 return 0;
00511         default:
00512                 wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise cipher %d",
00513                            sm->pairwise_cipher);
00514                 return -1;
00515         }
00516 
00517         if (sm->proto == WPA_PROTO_RSN) {
00518                 key_rsc = null_rsc;
00519         } else {
00520                 key_rsc = key->key_rsc;
00521                 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
00522         }
00523 
00524         if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
00525                            (u8 *) sm->ptk.tk1, keylen) < 0) {
00526                 wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the "
00527                            "driver (alg=%d keylen=%d bssid=" MACSTR ")",
00528                            alg, keylen, MAC2STR(sm->bssid));
00529                 return -1;
00530         }
00531 
00532         if (sm->wpa_ptk_rekey) {
00533                 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
00534                 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
00535                                        sm, NULL);
00536         }
00537 
00538         return 0;
00539 }
00540 
00541 
00542 static int wpa_supplicant_check_group_cipher(int group_cipher,
00543                                              int keylen, int maxkeylen,
00544                                              int *key_rsc_len,
00545                                              enum wpa_alg *alg)
00546 {
00547         int ret = 0;
00548 
00549         switch (group_cipher) {
00550         case WPA_CIPHER_CCMP:
00551                 if (keylen != 16 || maxkeylen < 16) {
00552                         ret = -1;
00553                         break;
00554                 }
00555                 *key_rsc_len = 6;
00556                 *alg = WPA_ALG_CCMP;
00557                 break;
00558         case WPA_CIPHER_TKIP:
00559                 if (keylen != 32 || maxkeylen < 32) {
00560                         ret = -1;
00561                         break;
00562                 }
00563                 *key_rsc_len = 6;
00564                 *alg = WPA_ALG_TKIP;
00565                 break;
00566         case WPA_CIPHER_WEP104:
00567                 if (keylen != 13 || maxkeylen < 13) {
00568                         ret = -1;
00569                         break;
00570                 }
00571                 *key_rsc_len = 0;
00572                 *alg = WPA_ALG_WEP;
00573                 break;
00574         case WPA_CIPHER_WEP40:
00575                 if (keylen != 5 || maxkeylen < 5) {
00576                         ret = -1;
00577                         break;
00578                 }
00579                 *key_rsc_len = 0;
00580                 *alg = WPA_ALG_WEP;
00581                 break;
00582         default:
00583                 wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d",
00584                            group_cipher);
00585                 return -1;
00586         }
00587 
00588         if (ret < 0 ) {
00589                 wpa_printf(MSG_WARNING, "WPA: Unsupported %s Group Cipher key "
00590                            "length %d (%d).",
00591                            wpa_cipher_txt(group_cipher), keylen, maxkeylen);
00592         }
00593 
00594         return ret;
00595 }
00596 
00597 
00598 struct wpa_gtk_data {
00599         enum wpa_alg alg;
00600         int tx, key_rsc_len, keyidx;
00601         u8 gtk[32];
00602         int gtk_len;
00603 };
00604 
00605 
00606 static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
00607                                       const struct wpa_gtk_data *gd,
00608                                       const u8 *key_rsc)
00609 {
00610         const u8 *_gtk = gd->gtk;
00611         u8 gtk_buf[32];
00612 
00613         wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
00614         wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
00615                    "(keyidx=%d tx=%d len=%d).", gd->keyidx, gd->tx,
00616                    gd->gtk_len);
00617         wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
00618         if (sm->group_cipher == WPA_CIPHER_TKIP) {
00619                 /* Swap Tx/Rx keys for Michael MIC */
00620                 os_memcpy(gtk_buf, gd->gtk, 16);
00621                 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
00622                 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
00623                 _gtk = gtk_buf;
00624         }
00625         if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
00626                 if (wpa_sm_set_key(sm, gd->alg,
00627                                    (u8 *) "\xff\xff\xff\xff\xff\xff",
00628                                    gd->keyidx, 1, key_rsc, gd->key_rsc_len,
00629                                    _gtk, gd->gtk_len) < 0) {
00630                         wpa_printf(MSG_WARNING, "WPA: Failed to set "
00631                                    "GTK to the driver (Group only).");
00632                         return -1;
00633                 }
00634         } else if (wpa_sm_set_key(sm, gd->alg,
00635                                   (u8 *) "\xff\xff\xff\xff\xff\xff",
00636                                   gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
00637                                   _gtk, gd->gtk_len) < 0) {
00638                 wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
00639                            "the driver (alg=%d keylen=%d keyidx=%d)",
00640                            gd->alg, gd->gtk_len, gd->keyidx);
00641                 return -1;
00642         }
00643 
00644         return 0;
00645 }
00646 
00647 
00648 static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
00649                                                 int tx)
00650 {
00651         if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
00652                 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
00653                  * seemed to set this bit (incorrectly, since Tx is only when
00654                  * doing Group Key only APs) and without this workaround, the
00655                  * data connection does not work because wpa_supplicant
00656                  * configured non-zero keyidx to be used for unicast. */
00657                 wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but pairwise "
00658                            "keys are used - ignore Tx bit");
00659                 return 0;
00660         }
00661         return tx;
00662 }
00663 
00664 
00665 static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
00666                                        const struct wpa_eapol_key *key,
00667                                        const u8 *gtk, size_t gtk_len,
00668                                        int key_info)
00669 {
00670 #ifndef CONFIG_NO_WPA2
00671         struct wpa_gtk_data gd;
00672 
00673         /*
00674          * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
00675          * GTK KDE format:
00676          * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
00677          * Reserved [bits 0-7]
00678          * GTK
00679          */
00680 
00681         os_memset(&gd, 0, sizeof(gd));
00682         wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
00683                         gtk, gtk_len);
00684 
00685         if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
00686                 return -1;
00687 
00688         gd.keyidx = gtk[0] & 0x3;
00689         gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
00690                                                      !!(gtk[0] & BIT(2)));
00691         gtk += 2;
00692         gtk_len -= 2;
00693 
00694         os_memcpy(gd.gtk, gtk, gtk_len);
00695         gd.gtk_len = gtk_len;
00696 
00697         if (wpa_supplicant_check_group_cipher(sm->group_cipher,
00698                                               gtk_len, gtk_len,
00699                                               &gd.key_rsc_len, &gd.alg) ||
00700             wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) {
00701                 wpa_printf(MSG_DEBUG, "RSN: Failed to install GTK");
00702                 return -1;
00703         }
00704 
00705         wpa_supplicant_key_neg_complete(sm, sm->bssid,
00706                                         key_info & WPA_KEY_INFO_SECURE);
00707         return 0;
00708 #else /* CONFIG_NO_WPA2 */
00709         return -1;
00710 #endif /* CONFIG_NO_WPA2 */
00711 }
00712 
00713 
00714 static int ieee80211w_set_keys(struct wpa_sm *sm,
00715                                struct wpa_eapol_ie_parse *ie)
00716 {
00717 #ifdef CONFIG_IEEE80211W
00718         if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
00719                 return 0;
00720 
00721         if (ie->igtk) {
00722                 const struct wpa_igtk_kde *igtk;
00723                 u16 keyidx;
00724                 if (ie->igtk_len != sizeof(*igtk))
00725                         return -1;
00726                 igtk = (const struct wpa_igtk_kde *) ie->igtk;
00727                 keyidx = WPA_GET_LE16(igtk->keyid);
00728                 wpa_printf(MSG_DEBUG, "WPA: IGTK keyid %d "
00729                            "pn %02x%02x%02x%02x%02x%02x",
00730                            keyidx, MAC2STR(igtk->pn));
00731                 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
00732                                 igtk->igtk, WPA_IGTK_LEN);
00733                 if (keyidx > 4095) {
00734                         wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KeyID %d",
00735                                    keyidx);
00736                         return -1;
00737                 }
00738                 if (wpa_sm_set_key(sm, WPA_ALG_IGTK,
00739                                    (u8 *) "\xff\xff\xff\xff\xff\xff",
00740                                    keyidx, 0, igtk->pn, sizeof(igtk->pn),
00741                                    igtk->igtk, WPA_IGTK_LEN) < 0) {
00742                         wpa_printf(MSG_WARNING, "WPA: Failed to configure IGTK"
00743                                    " to the driver");
00744                         return -1;
00745                 }
00746         }
00747 
00748         return 0;
00749 #else /* CONFIG_IEEE80211W */
00750         return 0;
00751 #endif /* CONFIG_IEEE80211W */
00752 }
00753 
00754 
00755 static void wpa_report_ie_mismatch(struct wpa_sm *sm,
00756                                    const char *reason, const u8 *src_addr,
00757                                    const u8 *wpa_ie, size_t wpa_ie_len,
00758                                    const u8 *rsn_ie, size_t rsn_ie_len)
00759 {
00760         wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
00761                 reason, MAC2STR(src_addr));
00762 
00763         if (sm->ap_wpa_ie) {
00764                 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
00765                             sm->ap_wpa_ie, sm->ap_wpa_ie_len);
00766         }
00767         if (wpa_ie) {
00768                 if (!sm->ap_wpa_ie) {
00769                         wpa_printf(MSG_INFO, "WPA: No WPA IE in "
00770                                    "Beacon/ProbeResp");
00771                 }
00772                 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
00773                             wpa_ie, wpa_ie_len);
00774         }
00775 
00776         if (sm->ap_rsn_ie) {
00777                 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
00778                             sm->ap_rsn_ie, sm->ap_rsn_ie_len);
00779         }
00780         if (rsn_ie) {
00781                 if (!sm->ap_rsn_ie) {
00782                         wpa_printf(MSG_INFO, "WPA: No RSN IE in "
00783                                    "Beacon/ProbeResp");
00784                 }
00785                 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
00786                             rsn_ie, rsn_ie_len);
00787         }
00788 
00789         wpa_sm_disassociate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
00790 }
00791 
00792 
00793 #ifdef CONFIG_IEEE80211R
00794 
00795 static int ft_validate_mdie(struct wpa_sm *sm,
00796                             const unsigned char *src_addr,
00797                             struct wpa_eapol_ie_parse *ie,
00798                             const u8 *assoc_resp_mdie)
00799 {
00800         struct rsn_mdie *mdie;
00801 
00802         mdie = (struct rsn_mdie *) (ie->mdie + 2);
00803         if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
00804             os_memcmp(mdie->mobility_domain, sm->mobility_domain,
00805                       MOBILITY_DOMAIN_ID_LEN) != 0) {
00806                 wpa_printf(MSG_DEBUG, "FT: MDIE in msg 3/4 did not "
00807                            "match with the current mobility domain");
00808                 return -1;
00809         }
00810 
00811         if (assoc_resp_mdie &&
00812             (assoc_resp_mdie[1] != ie->mdie[1] ||
00813              os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
00814                 wpa_printf(MSG_DEBUG, "FT: MDIE mismatch");
00815                 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
00816                             ie->mdie, 2 + ie->mdie[1]);
00817                 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
00818                             assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
00819                 return -1;
00820         }
00821 
00822         return 0;
00823 }
00824 
00825 
00826 static int ft_validate_ftie(struct wpa_sm *sm,
00827                             const unsigned char *src_addr,
00828                             struct wpa_eapol_ie_parse *ie,
00829                             const u8 *assoc_resp_ftie)
00830 {
00831         if (ie->ftie == NULL) {
00832                 wpa_printf(MSG_DEBUG, "FT: No FTIE in EAPOL-Key msg 3/4");
00833                 return -1;
00834         }
00835 
00836         if (assoc_resp_ftie == NULL)
00837                 return 0;
00838 
00839         if (assoc_resp_ftie[1] != ie->ftie[1] ||
00840             os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
00841                 wpa_printf(MSG_DEBUG, "FT: FTIE mismatch");
00842                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
00843                             ie->ftie, 2 + ie->ftie[1]);
00844                 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
00845                             assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
00846                 return -1;
00847         }
00848 
00849         return 0;
00850 }
00851 
00852 
00853 static int ft_validate_rsnie(struct wpa_sm *sm,
00854                              const unsigned char *src_addr,
00855                              struct wpa_eapol_ie_parse *ie)
00856 {
00857         struct wpa_ie_data rsn;
00858 
00859         if (!ie->rsn_ie)
00860                 return 0;
00861 
00862         /*
00863          * Verify that PMKR1Name from EAPOL-Key message 3/4
00864          * matches with the value we derived.
00865          */
00866         if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
00867             rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
00868                 wpa_printf(MSG_DEBUG, "FT: No PMKR1Name in "
00869                            "FT 4-way handshake message 3/4");
00870                 return -1;
00871         }
00872 
00873         if (os_memcmp(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) {
00874                 wpa_printf(MSG_DEBUG, "FT: PMKR1Name mismatch in "
00875                            "FT 4-way handshake message 3/4");
00876                 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
00877                             rsn.pmkid, WPA_PMK_NAME_LEN);
00878                 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
00879                             sm->pmk_r1_name, WPA_PMK_NAME_LEN);
00880                 return -1;
00881         }
00882 
00883         return 0;
00884 }
00885 
00886 
00887 static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
00888                                          const unsigned char *src_addr,
00889                                          struct wpa_eapol_ie_parse *ie)
00890 {
00891         const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
00892 
00893         if (sm->assoc_resp_ies) {
00894                 pos = sm->assoc_resp_ies;
00895                 end = pos + sm->assoc_resp_ies_len;
00896                 while (pos + 2 < end) {
00897                         if (pos + 2 + pos[1] > end)
00898                                 break;
00899                         switch (*pos) {
00900                         case WLAN_EID_MOBILITY_DOMAIN:
00901                                 mdie = pos;
00902                                 break;
00903                         case WLAN_EID_FAST_BSS_TRANSITION:
00904                                 ftie = pos;
00905                                 break;
00906                         }
00907                         pos += 2 + pos[1];
00908                 }
00909         }
00910 
00911         if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
00912             ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
00913             ft_validate_rsnie(sm, src_addr, ie) < 0)
00914                 return -1;
00915 
00916         return 0;
00917 }
00918 
00919 #endif /* CONFIG_IEEE80211R */
00920 
00921 
00922 static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
00923                                       const unsigned char *src_addr,
00924                                       struct wpa_eapol_ie_parse *ie)
00925 {
00926         if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
00927                 wpa_printf(MSG_DEBUG, "WPA: No WPA/RSN IE for this AP known. "
00928                            "Trying to get from scan results");
00929                 if (wpa_sm_get_beacon_ie(sm) < 0) {
00930                         wpa_printf(MSG_WARNING, "WPA: Could not find AP from "
00931                                    "the scan results");
00932                 } else {
00933                         wpa_printf(MSG_DEBUG, "WPA: Found the current AP from "
00934                                    "updated scan results");
00935                 }
00936         }
00937 
00938         if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
00939             (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
00940                 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
00941                                        "with IE in Beacon/ProbeResp (no IE?)",
00942                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
00943                                        ie->rsn_ie, ie->rsn_ie_len);
00944                 return -1;
00945         }
00946 
00947         if ((ie->wpa_ie && sm->ap_wpa_ie &&
00948              (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
00949               os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
00950             (ie->rsn_ie && sm->ap_rsn_ie &&
00951              wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
00952                                 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
00953                                 ie->rsn_ie, ie->rsn_ie_len))) {
00954                 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
00955                                        "with IE in Beacon/ProbeResp",
00956                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
00957                                        ie->rsn_ie, ie->rsn_ie_len);
00958                 return -1;
00959         }
00960 
00961         if (sm->proto == WPA_PROTO_WPA &&
00962             ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
00963                 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
00964                                        "detected - RSN was enabled and RSN IE "
00965                                        "was in msg 3/4, but not in "
00966                                        "Beacon/ProbeResp",
00967                                        src_addr, ie->wpa_ie, ie->wpa_ie_len,
00968                                        ie->rsn_ie, ie->rsn_ie_len);
00969                 return -1;
00970         }
00971 
00972 #ifdef CONFIG_IEEE80211R
00973         if (wpa_key_mgmt_ft(sm->key_mgmt) &&
00974             wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
00975                 return -1;
00976 #endif /* CONFIG_IEEE80211R */
00977 
00978         return 0;
00979 }
00980 
00981 
00994 int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
00995                                const struct wpa_eapol_key *key,
00996                                u16 ver, u16 key_info,
00997                                const u8 *kde, size_t kde_len,
00998                                struct wpa_ptk *ptk)
00999 {
01000         size_t rlen;
01001         struct wpa_eapol_key *reply;
01002         u8 *rbuf;
01003 
01004         if (kde)
01005                 wpa_hexdump(MSG_DEBUG, "WPA: KDE for msg 4/4", kde, kde_len);
01006 
01007         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
01008                                   sizeof(*reply) + kde_len,
01009                                   &rlen, (void *) &reply);
01010         if (rbuf == NULL)
01011                 return -1;
01012 
01013         reply->type = sm->proto == WPA_PROTO_RSN ?
01014                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
01015         key_info &= WPA_KEY_INFO_SECURE;
01016         key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
01017         WPA_PUT_BE16(reply->key_info, key_info);
01018         if (sm->proto == WPA_PROTO_RSN)
01019                 WPA_PUT_BE16(reply->key_length, 0);
01020         else
01021                 os_memcpy(reply->key_length, key->key_length, 2);
01022         os_memcpy(reply->replay_counter, key->replay_counter,
01023                   WPA_REPLAY_COUNTER_LEN);
01024 
01025         WPA_PUT_BE16(reply->key_data_length, kde_len);
01026         if (kde)
01027                 os_memcpy(reply + 1, kde, kde_len);
01028 
01029         wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
01030         wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
01031                            rbuf, rlen, reply->key_mic);
01032 
01033         return 0;
01034 }
01035 
01036 
01037 static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
01038                                           const struct wpa_eapol_key *key,
01039                                           u16 ver)
01040 {
01041         u16 key_info, keylen, len;
01042         const u8 *pos;
01043         struct wpa_eapol_ie_parse ie;
01044 
01045         wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
01046         wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
01047                    MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
01048 
01049         key_info = WPA_GET_BE16(key->key_info);
01050 
01051         pos = (const u8 *) (key + 1);
01052         len = WPA_GET_BE16(key->key_data_length);
01053         wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);
01054         wpa_supplicant_parse_ies(pos, len, &ie);
01055         if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
01056                 wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");
01057                 goto failed;
01058         }
01059 #ifdef CONFIG_IEEE80211W
01060         if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
01061                 wpa_printf(MSG_WARNING, "WPA: IGTK KDE in unencrypted key "
01062                            "data");
01063                 goto failed;
01064         }
01065 
01066         if (ie.igtk && ie.igtk_len != sizeof(struct wpa_igtk_kde)) {
01067                 wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KDE length %lu",
01068                            (unsigned long) ie.igtk_len);
01069                 goto failed;
01070         }
01071 #endif /* CONFIG_IEEE80211W */
01072 
01073         if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
01074                 goto failed;
01075 
01076         if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
01077                 wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
01078                            "Handshake differs from 3 of 4-Way Handshake - drop"
01079                            " packet (src=" MACSTR ")", MAC2STR(sm->bssid));
01080                 goto failed;
01081         }
01082 
01083         keylen = WPA_GET_BE16(key->key_length);
01084         switch (sm->pairwise_cipher) {
01085         case WPA_CIPHER_CCMP:
01086                 if (keylen != 16) {
01087                         wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
01088                                    "%d (src=" MACSTR ")",
01089                                    keylen, MAC2STR(sm->bssid));
01090                         goto failed;
01091                 }
01092                 break;
01093         case WPA_CIPHER_TKIP:
01094                 if (keylen != 32) {
01095                         wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
01096                                    "%d (src=" MACSTR ")",
01097                                    keylen, MAC2STR(sm->bssid));
01098                         goto failed;
01099                 }
01100                 break;
01101         }
01102 
01103         if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
01104                                        NULL, 0, &sm->ptk)) {
01105                 goto failed;
01106         }
01107 
01108         /* SNonce was successfully used in msg 3/4, so mark it to be renewed
01109          * for the next 4-Way Handshake. If msg 3 is received again, the old
01110          * SNonce will still be used to avoid changing PTK. */
01111         sm->renew_snonce = 1;
01112 
01113         if (key_info & WPA_KEY_INFO_INSTALL) {
01114                 if (wpa_supplicant_install_ptk(sm, key))
01115                         goto failed;
01116         }
01117 
01118         if (key_info & WPA_KEY_INFO_SECURE) {
01119                 wpa_sm_mlme_setprotection(
01120                         sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
01121                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
01122                 eapol_sm_notify_portValid(sm->eapol, TRUE);
01123         }
01124         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
01125 
01126         if (ie.gtk &&
01127             wpa_supplicant_pairwise_gtk(sm, key,
01128                                         ie.gtk, ie.gtk_len, key_info) < 0) {
01129                 wpa_printf(MSG_INFO, "RSN: Failed to configure GTK");
01130                 goto failed;
01131         }
01132 
01133         if (ieee80211w_set_keys(sm, &ie) < 0) {
01134                 wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");
01135                 goto failed;
01136         }
01137 
01138         return;
01139 
01140 failed:
01141         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
01142 }
01143 
01144 
01145 static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
01146                                              const u8 *keydata,
01147                                              size_t keydatalen,
01148                                              u16 key_info,
01149                                              struct wpa_gtk_data *gd)
01150 {
01151         int maxkeylen;
01152         struct wpa_eapol_ie_parse ie;
01153 
01154         wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
01155         wpa_supplicant_parse_ies(keydata, keydatalen, &ie);
01156         if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
01157                 wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");
01158                 return -1;
01159         }
01160         if (ie.gtk == NULL) {
01161                 wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key msg 1/2");
01162                 return -1;
01163         }
01164         maxkeylen = gd->gtk_len = ie.gtk_len - 2;
01165 
01166         if (wpa_supplicant_check_group_cipher(sm->group_cipher,
01167                                               gd->gtk_len, maxkeylen,
01168                                               &gd->key_rsc_len, &gd->alg))
01169                 return -1;
01170 
01171         wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",
01172                     ie.gtk, ie.gtk_len);
01173         gd->keyidx = ie.gtk[0] & 0x3;
01174         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
01175                                                       !!(ie.gtk[0] & BIT(2)));
01176         if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
01177                 wpa_printf(MSG_INFO, "RSN: Too long GTK in GTK IE "
01178                            "(len=%lu)", (unsigned long) ie.gtk_len - 2);
01179                 return -1;
01180         }
01181         os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
01182 
01183         if (ieee80211w_set_keys(sm, &ie) < 0)
01184                 wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");
01185 
01186         return 0;
01187 }
01188 
01189 
01190 static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
01191                                              const struct wpa_eapol_key *key,
01192                                              size_t keydatalen, int key_info,
01193                                              size_t extra_len, u16 ver,
01194                                              struct wpa_gtk_data *gd)
01195 {
01196         size_t maxkeylen;
01197         u8 ek[32];
01198 
01199         gd->gtk_len = WPA_GET_BE16(key->key_length);
01200         maxkeylen = keydatalen;
01201         if (keydatalen > extra_len) {
01202                 wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
01203                            " key_data_length=%lu > extra_len=%lu",
01204                            (unsigned long) keydatalen,
01205                            (unsigned long) extra_len);
01206                 return -1;
01207         }
01208         if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
01209                 if (maxkeylen < 8) {
01210                         wpa_printf(MSG_INFO, "WPA: Too short maxkeylen (%lu)",
01211                                    (unsigned long) maxkeylen);
01212                         return -1;
01213                 }
01214                 maxkeylen -= 8;
01215         }
01216 
01217         if (wpa_supplicant_check_group_cipher(sm->group_cipher,
01218                                               gd->gtk_len, maxkeylen,
01219                                               &gd->key_rsc_len, &gd->alg))
01220                 return -1;
01221 
01222         gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
01223                 WPA_KEY_INFO_KEY_INDEX_SHIFT;
01224         if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
01225                 os_memcpy(ek, key->key_iv, 16);
01226                 os_memcpy(ek + 16, sm->ptk.kek, 16);
01227                 if (keydatalen > sizeof(gd->gtk)) {
01228                         wpa_printf(MSG_WARNING, "WPA: RC4 key data "
01229                                    "too long (%lu)",
01230                                    (unsigned long) keydatalen);
01231                         return -1;
01232                 }
01233                 os_memcpy(gd->gtk, key + 1, keydatalen);
01234                 if (rc4_skip(ek, 32, 256, gd->gtk, keydatalen)) {
01235                         wpa_printf(MSG_ERROR, "WPA: RC4 failed");
01236                         return -1;
01237                 }
01238         } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
01239                 if (keydatalen % 8) {
01240                         wpa_printf(MSG_WARNING, "WPA: Unsupported AES-WRAP "
01241                                    "len %lu", (unsigned long) keydatalen);
01242                         return -1;
01243                 }
01244                 if (maxkeylen > sizeof(gd->gtk)) {
01245                         wpa_printf(MSG_WARNING, "WPA: AES-WRAP key data "
01246                                    "too long (keydatalen=%lu maxkeylen=%lu)",
01247                                    (unsigned long) keydatalen,
01248                                    (unsigned long) maxkeylen);
01249                         return -1;
01250                 }
01251                 if (aes_unwrap(sm->ptk.kek, maxkeylen / 8,
01252                                (const u8 *) (key + 1), gd->gtk)) {
01253                         wpa_printf(MSG_WARNING, "WPA: AES unwrap "
01254                                    "failed - could not decrypt GTK");
01255                         return -1;
01256                 }
01257         } else {
01258                 wpa_printf(MSG_WARNING, "WPA: Unsupported key_info type %d",
01259                            ver);
01260                 return -1;
01261         }
01262         gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
01263                 sm, !!(key_info & WPA_KEY_INFO_TXRX));
01264         return 0;
01265 }
01266 
01267 
01268 static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
01269                                       const struct wpa_eapol_key *key,
01270                                       int ver, u16 key_info)
01271 {
01272         size_t rlen;
01273         struct wpa_eapol_key *reply;
01274         u8 *rbuf;
01275 
01276         rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
01277                                   sizeof(*reply), &rlen, (void *) &reply);
01278         if (rbuf == NULL)
01279                 return -1;
01280 
01281         reply->type = sm->proto == WPA_PROTO_RSN ?
01282                 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
01283         key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
01284         key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
01285         WPA_PUT_BE16(reply->key_info, key_info);
01286         if (sm->proto == WPA_PROTO_RSN)
01287                 WPA_PUT_BE16(reply->key_length, 0);
01288         else
01289                 os_memcpy(reply->key_length, key->key_length, 2);
01290         os_memcpy(reply->replay_counter, key->replay_counter,
01291                   WPA_REPLAY_COUNTER_LEN);
01292 
01293         WPA_PUT_BE16(reply->key_data_length, 0);
01294 
01295         wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
01296         wpa_eapol_key_send(sm, sm->ptk.kck, ver, sm->bssid, ETH_P_EAPOL,
01297                            rbuf, rlen, reply->key_mic);
01298 
01299         return 0;
01300 }
01301 
01302 
01303 static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
01304                                           const unsigned char *src_addr,
01305                                           const struct wpa_eapol_key *key,
01306                                           int extra_len, u16 ver)
01307 {
01308         u16 key_info, keydatalen;
01309         int rekey, ret;
01310         struct wpa_gtk_data gd;
01311 
01312         os_memset(&gd, 0, sizeof(gd));
01313 
01314         rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
01315         wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from "
01316                    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
01317 
01318         key_info = WPA_GET_BE16(key->key_info);
01319         keydatalen = WPA_GET_BE16(key->key_data_length);
01320 
01321         if (sm->proto == WPA_PROTO_RSN) {
01322                 ret = wpa_supplicant_process_1_of_2_rsn(sm,
01323                                                         (const u8 *) (key + 1),
01324                                                         keydatalen, key_info,
01325                                                         &gd);
01326         } else {
01327                 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, keydatalen,
01328                                                         key_info, extra_len,
01329                                                         ver, &gd);
01330         }
01331 
01332         wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
01333 
01334         if (ret)
01335                 goto failed;
01336 
01337         if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
01338             wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
01339                 goto failed;
01340 
01341         if (rekey) {
01342                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
01343                         "completed with " MACSTR " [GTK=%s]",
01344                         MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
01345                 wpa_sm_cancel_auth_timeout(sm);
01346                 wpa_sm_set_state(sm, WPA_COMPLETED);
01347         } else {
01348                 wpa_supplicant_key_neg_complete(sm, sm->bssid,
01349                                                 key_info &
01350                                                 WPA_KEY_INFO_SECURE);
01351         }
01352         return;
01353 
01354 failed:
01355         wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
01356 }
01357 
01358 
01359 static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
01360                                                struct wpa_eapol_key *key,
01361                                                u16 ver,
01362                                                const u8 *buf, size_t len)
01363 {
01364         u8 mic[16];
01365         int ok = 0;
01366 
01367         os_memcpy(mic, key->key_mic, 16);
01368         if (sm->tptk_set) {
01369                 os_memset(key->key_mic, 0, 16);
01370                 wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
01371                                   key->key_mic);
01372                 if (os_memcmp(mic, key->key_mic, 16) != 0) {
01373                         wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
01374                                    "when using TPTK - ignoring TPTK");
01375                 } else {
01376                         ok = 1;
01377                         sm->tptk_set = 0;
01378                         sm->ptk_set = 1;
01379                         os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
01380                 }
01381         }
01382 
01383         if (!ok && sm->ptk_set) {
01384                 os_memset(key->key_mic, 0, 16);
01385                 wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
01386                                   key->key_mic);
01387                 if (os_memcmp(mic, key->key_mic, 16) != 0) {
01388                         wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
01389                                    "- dropping packet");
01390                         return -1;
01391                 }
01392                 ok = 1;
01393         }
01394 
01395         if (!ok) {
01396                 wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC "
01397                            "- dropping packet");
01398                 return -1;
01399         }
01400 
01401         os_memcpy(sm->rx_replay_counter, key->replay_counter,
01402                   WPA_REPLAY_COUNTER_LEN);
01403         sm->rx_replay_counter_set = 1;
01404         return 0;
01405 }
01406 
01407 
01408 /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
01409 static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
01410                                            struct wpa_eapol_key *key, u16 ver)
01411 {
01412         u16 keydatalen = WPA_GET_BE16(key->key_data_length);
01413 
01414         wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
01415                     (u8 *) (key + 1), keydatalen);
01416         if (!sm->ptk_set) {
01417                 wpa_printf(MSG_WARNING, "WPA: PTK not available, "
01418                            "cannot decrypt EAPOL-Key key data.");
01419                 return -1;
01420         }
01421 
01422         /* Decrypt key data here so that this operation does not need
01423          * to be implemented separately for each message type. */
01424         if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
01425                 u8 ek[32];
01426                 os_memcpy(ek, key->key_iv, 16);
01427                 os_memcpy(ek + 16, sm->ptk.kek, 16);
01428                 if (rc4_skip(ek, 32, 256, (u8 *) (key + 1), keydatalen)) {
01429                         wpa_printf(MSG_ERROR, "WPA: RC4 failed");
01430                         return -1;
01431                 }
01432         } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
01433                    ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
01434                 u8 *buf;
01435                 if (keydatalen % 8) {
01436                         wpa_printf(MSG_WARNING, "WPA: Unsupported "
01437                                    "AES-WRAP len %d", keydatalen);
01438                         return -1;
01439                 }
01440                 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
01441                 buf = os_malloc(keydatalen);
01442                 if (buf == NULL) {
01443                         wpa_printf(MSG_WARNING, "WPA: No memory for "
01444                                    "AES-UNWRAP buffer");
01445                         return -1;
01446                 }
01447                 if (aes_unwrap(sm->ptk.kek, keydatalen / 8,
01448                                (u8 *) (key + 1), buf)) {
01449                         os_free(buf);
01450                         wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - "
01451                                    "could not decrypt EAPOL-Key key data");
01452                         return -1;
01453                 }
01454                 os_memcpy(key + 1, buf, keydatalen);
01455                 os_free(buf);
01456                 WPA_PUT_BE16(key->key_data_length, keydatalen);
01457         } else {
01458                 wpa_printf(MSG_WARNING, "WPA: Unsupported key_info type %d",
01459                            ver);
01460                 return -1;
01461         }
01462         wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
01463                         (u8 *) (key + 1), keydatalen);
01464         return 0;
01465 }
01466 
01467 
01472 void wpa_sm_aborted_cached(struct wpa_sm *sm)
01473 {
01474         if (sm && sm->cur_pmksa) {
01475                 wpa_printf(MSG_DEBUG, "RSN: Cancelling PMKSA caching attempt");
01476                 sm->cur_pmksa = NULL;
01477         }
01478 }
01479 
01480 
01481 static void wpa_eapol_key_dump(const struct wpa_eapol_key *key)
01482 {
01483 #ifndef CONFIG_NO_STDOUT_DEBUG
01484         u16 key_info = WPA_GET_BE16(key->key_info);
01485 
01486         wpa_printf(MSG_DEBUG, "  EAPOL-Key type=%d", key->type);
01487         wpa_printf(MSG_DEBUG, "  key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s"
01488                    "%s%s%s%s%s%s%s)",
01489                    key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
01490                    (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
01491                    WPA_KEY_INFO_KEY_INDEX_SHIFT,
01492                    (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
01493                    key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
01494                    key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
01495                    key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
01496                    key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
01497                    key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
01498                    key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
01499                    key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
01500                    key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
01501         wpa_printf(MSG_DEBUG, "  key_length=%u key_data_length=%u",
01502                    WPA_GET_BE16(key->key_length),
01503                    WPA_GET_BE16(key->key_data_length));
01504         wpa_hexdump(MSG_DEBUG, "  replay_counter",
01505                     key->replay_counter, WPA_REPLAY_COUNTER_LEN);
01506         wpa_hexdump(MSG_DEBUG, "  key_nonce", key->key_nonce, WPA_NONCE_LEN);
01507         wpa_hexdump(MSG_DEBUG, "  key_iv", key->key_iv, 16);
01508         wpa_hexdump(MSG_DEBUG, "  key_rsc", key->key_rsc, 8);
01509         wpa_hexdump(MSG_DEBUG, "  key_id (reserved)", key->key_id, 8);
01510         wpa_hexdump(MSG_DEBUG, "  key_mic", key->key_mic, 16);
01511 #endif /* CONFIG_NO_STDOUT_DEBUG */
01512 }
01513 
01514 
01531 int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
01532                     const u8 *buf, size_t len)
01533 {
01534         size_t plen, data_len, extra_len;
01535         struct ieee802_1x_hdr *hdr;
01536         struct wpa_eapol_key *key;
01537         u16 key_info, ver;
01538         u8 *tmp;
01539         int ret = -1;
01540         struct wpa_peerkey *peerkey = NULL;
01541 
01542 #ifdef CONFIG_IEEE80211R
01543         sm->ft_completed = 0;
01544 #endif /* CONFIG_IEEE80211R */
01545 
01546         if (len < sizeof(*hdr) + sizeof(*key)) {
01547                 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA "
01548                            "EAPOL-Key (len %lu, expecting at least %lu)",
01549                            (unsigned long) len,
01550                            (unsigned long) sizeof(*hdr) + sizeof(*key));
01551                 return 0;
01552         }
01553 
01554         tmp = os_malloc(len);
01555         if (tmp == NULL)
01556                 return -1;
01557         os_memcpy(tmp, buf, len);
01558 
01559         hdr = (struct ieee802_1x_hdr *) tmp;
01560         key = (struct wpa_eapol_key *) (hdr + 1);
01561         plen = be_to_host16(hdr->length);
01562         data_len = plen + sizeof(*hdr);
01563         wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%lu",
01564                    hdr->version, hdr->type, (unsigned long) plen);
01565 
01566         if (hdr->version < EAPOL_VERSION) {
01567                 /* TODO: backwards compatibility */
01568         }
01569         if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
01570                 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, "
01571                         "not a Key frame", hdr->type);
01572                 ret = 0;
01573                 goto out;
01574         }
01575         if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {
01576                 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %lu "
01577                            "invalid (frame size %lu)",
01578                            (unsigned long) plen, (unsigned long) len);
01579                 ret = 0;
01580                 goto out;
01581         }
01582 
01583         if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
01584         {
01585                 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, "
01586                            "discarded", key->type);
01587                 ret = 0;
01588                 goto out;
01589         }
01590         wpa_eapol_key_dump(key);
01591 
01592         eapol_sm_notify_lower_layer_success(sm->eapol, 0);
01593         wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", tmp, len);
01594         if (data_len < len) {
01595                 wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "
01596                            "802.1X data", (unsigned long) len - data_len);
01597         }
01598         key_info = WPA_GET_BE16(key->key_info);
01599         ver = key_info & WPA_KEY_INFO_TYPE_MASK;
01600         if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
01601 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
01602             ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
01603 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
01604             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
01605                 wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "
01606                            "version %d.", ver);
01607                 goto out;
01608         }
01609 
01610 #ifdef CONFIG_IEEE80211R
01611         if (wpa_key_mgmt_ft(sm->key_mgmt)) {
01612                 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
01613                 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
01614                         wpa_printf(MSG_INFO, "FT: AP did not use "
01615                                    "AES-128-CMAC.");
01616                         goto out;
01617                 }
01618         } else
01619 #endif /* CONFIG_IEEE80211R */
01620 #ifdef CONFIG_IEEE80211W
01621         if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
01622                 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
01623                         wpa_printf(MSG_INFO, "WPA: AP did not use the "
01624                                    "negotiated AES-128-CMAC.");
01625                         goto out;
01626                 }
01627         } else
01628 #endif /* CONFIG_IEEE80211W */
01629         if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
01630             ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
01631                 wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
01632                            "descriptor version (%d) is not 2.", ver);
01633                 if (sm->group_cipher != WPA_CIPHER_CCMP &&
01634                     !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
01635                         /* Earlier versions of IEEE 802.11i did not explicitly
01636                          * require version 2 descriptor for all EAPOL-Key
01637                          * packets, so allow group keys to use version 1 if
01638                          * CCMP is not used for them. */
01639                         wpa_printf(MSG_INFO, "WPA: Backwards compatibility: "
01640                                    "allow invalid version for non-CCMP group "
01641                                    "keys");
01642                 } else
01643                         goto out;
01644         }
01645 
01646 #ifdef CONFIG_PEERKEY
01647         for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
01648                 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
01649                         break;
01650         }
01651 
01652         if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
01653                 if (!peerkey->initiator && peerkey->replay_counter_set &&
01654                     os_memcmp(key->replay_counter, peerkey->replay_counter,
01655                               WPA_REPLAY_COUNTER_LEN) <= 0) {
01656                         wpa_printf(MSG_WARNING, "RSN: EAPOL-Key Replay "
01657                                    "Counter did not increase (STK) - dropping "
01658                                    "packet");
01659                         goto out;
01660                 } else if (peerkey->initiator) {
01661                         u8 _tmp[WPA_REPLAY_COUNTER_LEN];
01662                         os_memcpy(_tmp, key->replay_counter,
01663                                   WPA_REPLAY_COUNTER_LEN);
01664                         inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
01665                         if (os_memcmp(_tmp, peerkey->replay_counter,
01666                                       WPA_REPLAY_COUNTER_LEN) != 0) {
01667                                 wpa_printf(MSG_DEBUG, "RSN: EAPOL-Key Replay "
01668                                            "Counter did not match (STK) - "
01669                                            "dropping packet");
01670                                 goto out;
01671                         }
01672                 }
01673         }
01674 
01675         if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
01676                 wpa_printf(MSG_INFO, "RSN: Ack bit in key_info from STK peer");
01677                 goto out;
01678         }
01679 #endif /* CONFIG_PEERKEY */
01680 
01681         if (!peerkey && sm->rx_replay_counter_set &&
01682             os_memcmp(key->replay_counter, sm->rx_replay_counter,
01683                       WPA_REPLAY_COUNTER_LEN) <= 0) {
01684                 wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not"
01685                            " increase - dropping packet");
01686                 goto out;
01687         }
01688 
01689         if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
01690 #ifdef CONFIG_PEERKEY
01691             && (peerkey == NULL || !peerkey->initiator)
01692 #endif /* CONFIG_PEERKEY */
01693                 ) {
01694                 wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info");
01695                 goto out;
01696         }
01697 
01698         if (key_info & WPA_KEY_INFO_REQUEST) {
01699                 wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - "
01700                            "dropped");
01701                 goto out;
01702         }
01703 
01704         if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
01705             wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
01706                 goto out;
01707 
01708 #ifdef CONFIG_PEERKEY
01709         if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
01710             peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp, data_len))
01711                 goto out;
01712 #endif /* CONFIG_PEERKEY */
01713 
01714         extra_len = data_len - sizeof(*hdr) - sizeof(*key);
01715 
01716         if (WPA_GET_BE16(key->key_data_length) > extra_len) {
01717                 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
01718                         "frame - key_data overflow (%d > %lu)",
01719                         WPA_GET_BE16(key->key_data_length),
01720                         (unsigned long) extra_len);
01721                 goto out;
01722         }
01723         extra_len = WPA_GET_BE16(key->key_data_length);
01724 
01725         if (sm->proto == WPA_PROTO_RSN &&
01726             (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
01727                 if (wpa_supplicant_decrypt_key_data(sm, key, ver))
01728                         goto out;
01729                 extra_len = WPA_GET_BE16(key->key_data_length);
01730         }
01731 
01732         if (key_info & WPA_KEY_INFO_KEY_TYPE) {
01733                 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
01734                         wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key "
01735                                    "(Pairwise) with non-zero key index");
01736                         goto out;
01737                 }
01738                 if (peerkey) {
01739                         /* PeerKey 4-Way Handshake */
01740                         peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver);
01741                 } else if (key_info & WPA_KEY_INFO_MIC) {
01742                         /* 3/4 4-Way Handshake */
01743                         wpa_supplicant_process_3_of_4(sm, key, ver);
01744                 } else {
01745                         /* 1/4 4-Way Handshake */
01746                         wpa_supplicant_process_1_of_4(sm, src_addr, key,
01747                                                       ver);
01748                 }
01749         } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
01750                 /* PeerKey SMK Handshake */
01751                 peerkey_rx_eapol_smk(sm, src_addr, key, extra_len, key_info,
01752                                      ver);
01753         } else {
01754                 if (key_info & WPA_KEY_INFO_MIC) {
01755                         /* 1/2 Group Key Handshake */
01756                         wpa_supplicant_process_1_of_2(sm, src_addr, key,
01757                                                       extra_len, ver);
01758                 } else {
01759                         wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) "
01760                                    "without Mic bit - dropped");
01761                 }
01762         }
01763 
01764         ret = 1;
01765 
01766 out:
01767         os_free(tmp);
01768         return ret;
01769 }
01770 
01771 
01772 #ifdef CONFIG_CTRL_IFACE
01773 static int wpa_cipher_bits(int cipher)
01774 {
01775         switch (cipher) {
01776         case WPA_CIPHER_CCMP:
01777                 return 128;
01778         case WPA_CIPHER_TKIP:
01779                 return 256;
01780         case WPA_CIPHER_WEP104:
01781                 return 104;
01782         case WPA_CIPHER_WEP40:
01783                 return 40;
01784         default:
01785                 return 0;
01786         }
01787 }
01788 
01789 
01790 static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
01791 {
01792         switch (sm->key_mgmt) {
01793         case WPA_KEY_MGMT_IEEE8021X:
01794                 return (sm->proto == WPA_PROTO_RSN ?
01795                         RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
01796                         WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
01797         case WPA_KEY_MGMT_PSK:
01798                 return (sm->proto == WPA_PROTO_RSN ?
01799                         RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
01800                         WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
01801 #ifdef CONFIG_IEEE80211R
01802         case WPA_KEY_MGMT_FT_IEEE8021X:
01803                 return RSN_AUTH_KEY_MGMT_FT_802_1X;
01804         case WPA_KEY_MGMT_FT_PSK:
01805                 return RSN_AUTH_KEY_MGMT_FT_PSK;
01806 #endif /* CONFIG_IEEE80211R */
01807 #ifdef CONFIG_IEEE80211W
01808         case WPA_KEY_MGMT_IEEE8021X_SHA256:
01809                 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
01810         case WPA_KEY_MGMT_PSK_SHA256:
01811                 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
01812 #endif /* CONFIG_IEEE80211W */
01813         case WPA_KEY_MGMT_WPA_NONE:
01814                 return WPA_AUTH_KEY_MGMT_NONE;
01815         default:
01816                 return 0;
01817         }
01818 }
01819 
01820 
01821 static u32 wpa_cipher_suite(struct wpa_sm *sm, int cipher)
01822 {
01823         switch (cipher) {
01824         case WPA_CIPHER_CCMP:
01825                 return (sm->proto == WPA_PROTO_RSN ?
01826                         RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
01827         case WPA_CIPHER_TKIP:
01828                 return (sm->proto == WPA_PROTO_RSN ?
01829                         RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
01830         case WPA_CIPHER_WEP104:
01831                 return (sm->proto == WPA_PROTO_RSN ?
01832                         RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
01833         case WPA_CIPHER_WEP40:
01834                 return (sm->proto == WPA_PROTO_RSN ?
01835                         RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
01836         case WPA_CIPHER_NONE:
01837                 return (sm->proto == WPA_PROTO_RSN ?
01838                         RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
01839         default:
01840                 return 0;
01841         }
01842 }
01843 
01844 
01845 #define RSN_SUITE "%02x-%02x-%02x-%d"
01846 #define RSN_SUITE_ARG(s) \
01847 ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
01848 
01858 int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
01859 {
01860         char pmkid_txt[PMKID_LEN * 2 + 1];
01861         int rsna, ret;
01862         size_t len;
01863 
01864         if (sm->cur_pmksa) {
01865                 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
01866                                  sm->cur_pmksa->pmkid, PMKID_LEN);
01867         } else
01868                 pmkid_txt[0] = '\0';
01869 
01870         if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
01871              wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
01872             sm->proto == WPA_PROTO_RSN)
01873                 rsna = 1;
01874         else
01875                 rsna = 0;
01876 
01877         ret = os_snprintf(buf, buflen,
01878                           "dot11RSNAOptionImplemented=TRUE\n"
01879                           "dot11RSNAPreauthenticationImplemented=TRUE\n"
01880                           "dot11RSNAEnabled=%s\n"
01881                           "dot11RSNAPreauthenticationEnabled=%s\n"
01882                           "dot11RSNAConfigVersion=%d\n"
01883                           "dot11RSNAConfigPairwiseKeysSupported=5\n"
01884                           "dot11RSNAConfigGroupCipherSize=%d\n"
01885                           "dot11RSNAConfigPMKLifetime=%d\n"
01886                           "dot11RSNAConfigPMKReauthThreshold=%d\n"
01887                           "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
01888                           "dot11RSNAConfigSATimeout=%d\n",
01889                           rsna ? "TRUE" : "FALSE",
01890                           rsna ? "TRUE" : "FALSE",
01891                           RSN_VERSION,
01892                           wpa_cipher_bits(sm->group_cipher),
01893                           sm->dot11RSNAConfigPMKLifetime,
01894                           sm->dot11RSNAConfigPMKReauthThreshold,
01895                           sm->dot11RSNAConfigSATimeout);
01896         if (ret < 0 || (size_t) ret >= buflen)
01897                 return 0;
01898         len = ret;
01899 
01900         ret = os_snprintf(
01901                 buf + len, buflen - len,
01902                 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
01903                 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
01904                 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
01905                 "dot11RSNAPMKIDUsed=%s\n"
01906                 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
01907                 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
01908                 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
01909                 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
01910                 "dot11RSNA4WayHandshakeFailures=%u\n",
01911                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
01912                 RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->pairwise_cipher)),
01913                 RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),
01914                 pmkid_txt,
01915                 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
01916                 RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->pairwise_cipher)),
01917                 RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),
01918                 sm->dot11RSNA4WayHandshakeFailures);
01919         if (ret >= 0 && (size_t) ret < buflen)
01920                 len += ret;
01921 
01922         return (int) len;
01923 }
01924 #endif /* CONFIG_CTRL_IFACE */
01925 
01926 
01927 static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
01928                                  void *ctx, int replace)
01929 {
01930         struct wpa_sm *sm = ctx;
01931 
01932         if (sm->cur_pmksa == entry ||
01933             (sm->pmk_len == entry->pmk_len &&
01934              os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
01935                 wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");
01936                 sm->cur_pmksa = NULL;
01937 
01938                 if (replace) {
01939                         /* A new entry is being added, so no need to
01940                          * deauthenticate in this case. This happens when EAP
01941                          * authentication is completed again (reauth or failed
01942                          * PMKSA caching attempt). */
01943                         return;
01944                 }
01945 
01946                 os_memset(sm->pmk, 0, sizeof(sm->pmk));
01947                 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
01948         }
01949 }
01950 
01951 
01960 struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
01961 {
01962         struct wpa_sm *sm;
01963 
01964         sm = os_zalloc(sizeof(*sm));
01965         if (sm == NULL)
01966                 return NULL;
01967         dl_list_init(&sm->pmksa_candidates);
01968         sm->renew_snonce = 1;
01969         sm->ctx = ctx;
01970 
01971         sm->dot11RSNAConfigPMKLifetime = 43200;
01972         sm->dot11RSNAConfigPMKReauthThreshold = 70;
01973         sm->dot11RSNAConfigSATimeout = 60;
01974 
01975         sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
01976         if (sm->pmksa == NULL) {
01977                 wpa_printf(MSG_ERROR, "RSN: PMKSA cache initialization "
01978                            "failed");
01979                 os_free(sm);
01980                 return NULL;
01981         }
01982 
01983         return sm;
01984 }
01985 
01986 
01991 void wpa_sm_deinit(struct wpa_sm *sm)
01992 {
01993         if (sm == NULL)
01994                 return;
01995         pmksa_cache_deinit(sm->pmksa);
01996         eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
01997         eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
01998         os_free(sm->assoc_wpa_ie);
01999         os_free(sm->ap_wpa_ie);
02000         os_free(sm->ap_rsn_ie);
02001         os_free(sm->ctx);
02002         peerkey_deinit(sm);
02003 #ifdef CONFIG_IEEE80211R
02004         os_free(sm->assoc_resp_ies);
02005 #endif /* CONFIG_IEEE80211R */
02006         os_free(sm);
02007 }
02008 
02009 
02018 void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
02019 {
02020         int clear_ptk = 1;
02021 
02022         if (sm == NULL)
02023                 return;
02024 
02025         wpa_printf(MSG_DEBUG, "WPA: Association event - clear replay counter");
02026         os_memcpy(sm->bssid, bssid, ETH_ALEN);
02027         os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
02028         sm->rx_replay_counter_set = 0;
02029         sm->renew_snonce = 1;
02030         if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
02031                 rsn_preauth_deinit(sm);
02032 
02033 #ifdef CONFIG_IEEE80211R
02034         if (wpa_ft_is_completed(sm)) {
02035                 /*
02036                  * Clear portValid to kick EAPOL state machine to re-enter
02037                  * AUTHENTICATED state to get the EAPOL port Authorized.
02038                  */
02039                 eapol_sm_notify_portValid(sm->eapol, FALSE);
02040                 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
02041 
02042                 /* Prepare for the next transition */
02043                 wpa_ft_prepare_auth_request(sm, NULL);
02044 
02045                 clear_ptk = 0;
02046         }
02047 #endif /* CONFIG_IEEE80211R */
02048 
02049         if (clear_ptk) {
02050                 /*
02051                  * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
02052                  * this is not part of a Fast BSS Transition.
02053                  */
02054                 wpa_printf(MSG_DEBUG, "WPA: Clear old PTK");
02055                 sm->ptk_set = 0;
02056                 sm->tptk_set = 0;
02057         }
02058 }
02059 
02060 
02068 void wpa_sm_notify_disassoc(struct wpa_sm *sm)
02069 {
02070         rsn_preauth_deinit(sm);
02071         if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
02072                 sm->dot11RSNA4WayHandshakeFailures++;
02073 }
02074 
02075 
02084 void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len)
02085 {
02086         if (sm == NULL)
02087                 return;
02088 
02089         sm->pmk_len = pmk_len;
02090         os_memcpy(sm->pmk, pmk, pmk_len);
02091 
02092 #ifdef CONFIG_IEEE80211R
02093         /* Set XXKey to be PSK for FT key derivation */
02094         sm->xxkey_len = pmk_len;
02095         os_memcpy(sm->xxkey, pmk, pmk_len);
02096 #endif /* CONFIG_IEEE80211R */
02097 }
02098 
02099 
02107 void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
02108 {
02109         if (sm == NULL)
02110                 return;
02111 
02112         if (sm->cur_pmksa) {
02113                 sm->pmk_len = sm->cur_pmksa->pmk_len;
02114                 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
02115         } else {
02116                 sm->pmk_len = PMK_LEN;
02117                 os_memset(sm->pmk, 0, PMK_LEN);
02118         }
02119 }
02120 
02121 
02127 void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
02128 {
02129         if (sm)
02130                 sm->fast_reauth = fast_reauth;
02131 }
02132 
02133 
02139 void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
02140 {
02141         if (sm == NULL)
02142                 return;
02143         sm->scard_ctx = scard_ctx;
02144         if (sm->preauth_eapol)
02145                 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
02146 }
02147 
02148 
02158 void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
02159 {
02160         if (!sm)
02161                 return;
02162 
02163         if (config) {
02164                 sm->network_ctx = config->network_ctx;
02165                 sm->peerkey_enabled = config->peerkey_enabled;
02166                 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
02167                 sm->proactive_key_caching = config->proactive_key_caching;
02168                 sm->eap_workaround = config->eap_workaround;
02169                 sm->eap_conf_ctx = config->eap_conf_ctx;
02170                 if (config->ssid) {
02171                         os_memcpy(sm->ssid, config->ssid, config->ssid_len);
02172                         sm->ssid_len = config->ssid_len;
02173                 } else
02174                         sm->ssid_len = 0;
02175                 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
02176         } else {
02177                 sm->network_ctx = NULL;
02178                 sm->peerkey_enabled = 0;
02179                 sm->allowed_pairwise_cipher = 0;
02180                 sm->proactive_key_caching = 0;
02181                 sm->eap_workaround = 0;
02182                 sm->eap_conf_ctx = NULL;
02183                 sm->ssid_len = 0;
02184                 sm->wpa_ptk_rekey = 0;
02185         }
02186         if (config == NULL || config->network_ctx != sm->network_ctx)
02187                 pmksa_cache_notify_reconfig(sm->pmksa);
02188 }
02189 
02190 
02196 void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
02197 {
02198         if (sm)
02199                 os_memcpy(sm->own_addr, addr, ETH_ALEN);
02200 }
02201 
02202 
02209 void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
02210                        const char *bridge_ifname)
02211 {
02212         if (sm) {
02213                 sm->ifname = ifname;
02214                 sm->bridge_ifname = bridge_ifname;
02215         }
02216 }
02217 
02218 
02224 void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
02225 {
02226         if (sm)
02227                 sm->eapol = eapol;
02228 }
02229 
02230 
02238 int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
02239                      unsigned int value)
02240 {
02241         int ret = 0;
02242 
02243         if (sm == NULL)
02244                 return -1;
02245 
02246         switch (param) {
02247         case RSNA_PMK_LIFETIME:
02248                 if (value > 0)
02249                         sm->dot11RSNAConfigPMKLifetime = value;
02250                 else
02251                         ret = -1;
02252                 break;
02253         case RSNA_PMK_REAUTH_THRESHOLD:
02254                 if (value > 0 && value <= 100)
02255                         sm->dot11RSNAConfigPMKReauthThreshold = value;
02256                 else
02257                         ret = -1;
02258                 break;
02259         case RSNA_SA_TIMEOUT:
02260                 if (value > 0)
02261                         sm->dot11RSNAConfigSATimeout = value;
02262                 else
02263                         ret = -1;
02264                 break;
02265         case WPA_PARAM_PROTO:
02266                 sm->proto = value;
02267                 break;
02268         case WPA_PARAM_PAIRWISE:
02269                 sm->pairwise_cipher = value;
02270                 break;
02271         case WPA_PARAM_GROUP:
02272                 sm->group_cipher = value;
02273                 break;
02274         case WPA_PARAM_KEY_MGMT:
02275                 sm->key_mgmt = value;
02276                 break;
02277 #ifdef CONFIG_IEEE80211W
02278         case WPA_PARAM_MGMT_GROUP:
02279                 sm->mgmt_group_cipher = value;
02280                 break;
02281 #endif /* CONFIG_IEEE80211W */
02282         case WPA_PARAM_RSN_ENABLED:
02283                 sm->rsn_enabled = value;
02284                 break;
02285         case WPA_PARAM_MFP:
02286                 sm->mfp = value;
02287                 break;
02288         default:
02289                 break;
02290         }
02291 
02292         return ret;
02293 }
02294 
02295 
02302 unsigned int wpa_sm_get_param(struct wpa_sm *sm, enum wpa_sm_conf_params param)
02303 {
02304         if (sm == NULL)
02305                 return 0;
02306 
02307         switch (param) {
02308         case RSNA_PMK_LIFETIME:
02309                 return sm->dot11RSNAConfigPMKLifetime;
02310         case RSNA_PMK_REAUTH_THRESHOLD:
02311                 return sm->dot11RSNAConfigPMKReauthThreshold;
02312         case RSNA_SA_TIMEOUT:
02313                 return sm->dot11RSNAConfigSATimeout;
02314         case WPA_PARAM_PROTO:
02315                 return sm->proto;
02316         case WPA_PARAM_PAIRWISE:
02317                 return sm->pairwise_cipher;
02318         case WPA_PARAM_GROUP:
02319                 return sm->group_cipher;
02320         case WPA_PARAM_KEY_MGMT:
02321                 return sm->key_mgmt;
02322 #ifdef CONFIG_IEEE80211W
02323         case WPA_PARAM_MGMT_GROUP:
02324                 return sm->mgmt_group_cipher;
02325 #endif /* CONFIG_IEEE80211W */
02326         case WPA_PARAM_RSN_ENABLED:
02327                 return sm->rsn_enabled;
02328         default:
02329                 return 0;
02330         }
02331 }
02332 
02333 
02346 int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
02347                       int verbose)
02348 {
02349         char *pos = buf, *end = buf + buflen;
02350         int ret;
02351 
02352         ret = os_snprintf(pos, end - pos,
02353                           "pairwise_cipher=%s\n"
02354                           "group_cipher=%s\n"
02355                           "key_mgmt=%s\n",
02356                           wpa_cipher_txt(sm->pairwise_cipher),
02357                           wpa_cipher_txt(sm->group_cipher),
02358                           wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
02359         if (ret < 0 || ret >= end - pos)
02360                 return pos - buf;
02361         pos += ret;
02362         return pos - buf;
02363 }
02364 
02365 
02373 int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
02374                                     size_t *wpa_ie_len)
02375 {
02376         int res;
02377 
02378         if (sm == NULL)
02379                 return -1;
02380 
02381         res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
02382         if (res < 0)
02383                 return -1;
02384         *wpa_ie_len = res;
02385 
02386         wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
02387                     wpa_ie, *wpa_ie_len);
02388 
02389         if (sm->assoc_wpa_ie == NULL) {
02390                 /*
02391                  * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
02392                  * the correct version of the IE even if PMKSA caching is
02393                  * aborted (which would remove PMKID from IE generation).
02394                  */
02395                 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
02396                 if (sm->assoc_wpa_ie == NULL)
02397                         return -1;
02398 
02399                 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
02400                 sm->assoc_wpa_ie_len = *wpa_ie_len;
02401         }
02402 
02403         return 0;
02404 }
02405 
02406 
02418 int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
02419 {
02420         if (sm == NULL)
02421                 return -1;
02422 
02423         os_free(sm->assoc_wpa_ie);
02424         if (ie == NULL || len == 0) {
02425                 wpa_printf(MSG_DEBUG, "WPA: clearing own WPA/RSN IE");
02426                 sm->assoc_wpa_ie = NULL;
02427                 sm->assoc_wpa_ie_len = 0;
02428         } else {
02429                 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
02430                 sm->assoc_wpa_ie = os_malloc(len);
02431                 if (sm->assoc_wpa_ie == NULL)
02432                         return -1;
02433 
02434                 os_memcpy(sm->assoc_wpa_ie, ie, len);
02435                 sm->assoc_wpa_ie_len = len;
02436         }
02437 
02438         return 0;
02439 }
02440 
02441 
02452 int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
02453 {
02454         if (sm == NULL)
02455                 return -1;
02456 
02457         os_free(sm->ap_wpa_ie);
02458         if (ie == NULL || len == 0) {
02459                 wpa_printf(MSG_DEBUG, "WPA: clearing AP WPA IE");
02460                 sm->ap_wpa_ie = NULL;
02461                 sm->ap_wpa_ie_len = 0;
02462         } else {
02463                 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
02464                 sm->ap_wpa_ie = os_malloc(len);
02465                 if (sm->ap_wpa_ie == NULL)
02466                         return -1;
02467 
02468                 os_memcpy(sm->ap_wpa_ie, ie, len);
02469                 sm->ap_wpa_ie_len = len;
02470         }
02471 
02472         return 0;
02473 }
02474 
02475 
02486 int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
02487 {
02488         if (sm == NULL)
02489                 return -1;
02490 
02491         os_free(sm->ap_rsn_ie);
02492         if (ie == NULL || len == 0) {
02493                 wpa_printf(MSG_DEBUG, "WPA: clearing AP RSN IE");
02494                 sm->ap_rsn_ie = NULL;
02495                 sm->ap_rsn_ie_len = 0;
02496         } else {
02497                 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
02498                 sm->ap_rsn_ie = os_malloc(len);
02499                 if (sm->ap_rsn_ie == NULL)
02500                         return -1;
02501 
02502                 os_memcpy(sm->ap_rsn_ie, ie, len);
02503                 sm->ap_rsn_ie_len = len;
02504         }
02505 
02506         return 0;
02507 }
02508 
02509 
02519 int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
02520 {
02521         if (sm == NULL || sm->assoc_wpa_ie == NULL) {
02522                 wpa_printf(MSG_DEBUG, "WPA: No WPA/RSN IE available from "
02523                            "association info");
02524                 return -1;
02525         }
02526         if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
02527                 return -2;
02528         return 0;
02529 }
02530 
02531 
02532 int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
02533 {
02534 #ifndef CONFIG_NO_WPA2
02535         return pmksa_cache_list(sm->pmksa, buf, len);
02536 #else /* CONFIG_NO_WPA2 */
02537         return -1;
02538 #endif /* CONFIG_NO_WPA2 */
02539 }
02540 
02541 
02542 void wpa_sm_drop_sa(struct wpa_sm *sm)
02543 {
02544         wpa_printf(MSG_DEBUG, "WPA: Clear old PMK and PTK");
02545         sm->ptk_set = 0;
02546         sm->tptk_set = 0;
02547         os_memset(sm->pmk, 0, sizeof(sm->pmk));
02548         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
02549         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
02550 }
02551 
02552 
02553 int wpa_sm_has_ptk(struct wpa_sm *sm)
02554 {
02555         if (sm == NULL)
02556                 return 0;
02557         return sm->ptk_set;
02558 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:39