wpa.c

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

Generated on Sat Nov 21 23:16:49 2009 for hostapd by  doxygen 1.6.1