wpa_common.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "md5.h"
00020 #include "sha1.h"
00021 #include "sha256.h"
00022 #include "aes_wrap.h"
00023 #include "crypto.h"
00024 #include "ieee802_11_defs.h"
00025 #include "defs.h"
00026 #include "wpa_common.h"
00027 
00028 
00048 int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
00049                       u8 *mic)
00050 {
00051         u8 hash[SHA1_MAC_LEN];
00052 
00053         switch (ver) {
00054         case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
00055                 return hmac_md5(key, 16, buf, len, mic);
00056         case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
00057                 if (hmac_sha1(key, 16, buf, len, hash))
00058                         return -1;
00059                 os_memcpy(mic, hash, MD5_MAC_LEN);
00060                 break;
00061 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
00062         case WPA_KEY_INFO_TYPE_AES_128_CMAC:
00063                 return omac1_aes_128(key, buf, len, mic);
00064 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
00065         default:
00066                 return -1;
00067         }
00068 
00069         return 0;
00070 }
00071 
00072 
00096 void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
00097                     const u8 *addr1, const u8 *addr2,
00098                     const u8 *nonce1, const u8 *nonce2,
00099                     u8 *ptk, size_t ptk_len, int use_sha256)
00100 {
00101         u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
00102 
00103         if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
00104                 os_memcpy(data, addr1, ETH_ALEN);
00105                 os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
00106         } else {
00107                 os_memcpy(data, addr2, ETH_ALEN);
00108                 os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
00109         }
00110 
00111         if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
00112                 os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
00113                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
00114                           WPA_NONCE_LEN);
00115         } else {
00116                 os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
00117                 os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
00118                           WPA_NONCE_LEN);
00119         }
00120 
00121 #ifdef CONFIG_IEEE80211W
00122         if (use_sha256)
00123                 sha256_prf(pmk, pmk_len, label, data, sizeof(data),
00124                            ptk, ptk_len);
00125         else
00126 #endif /* CONFIG_IEEE80211W */
00127                 sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk,
00128                          ptk_len);
00129 
00130         wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
00131                    MAC2STR(addr1), MAC2STR(addr2));
00132         wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
00133         wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
00134 }
00135 
00136 
00137 #ifdef CONFIG_IEEE80211R
00138 int wpa_ft_mic(const u8 *kck, const u8 *sta_addr, const u8 *ap_addr,
00139                u8 transaction_seqnum, const u8 *mdie, size_t mdie_len,
00140                const u8 *ftie, size_t ftie_len,
00141                const u8 *rsnie, size_t rsnie_len,
00142                const u8 *ric, size_t ric_len, u8 *mic)
00143 {
00144         u8 *buf, *pos;
00145         size_t buf_len;
00146 
00147         buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
00148         buf = os_malloc(buf_len);
00149         if (buf == NULL)
00150                 return -1;
00151 
00152         pos = buf;
00153         os_memcpy(pos, sta_addr, ETH_ALEN);
00154         pos += ETH_ALEN;
00155         os_memcpy(pos, ap_addr, ETH_ALEN);
00156         pos += ETH_ALEN;
00157         *pos++ = transaction_seqnum;
00158         if (rsnie) {
00159                 os_memcpy(pos, rsnie, rsnie_len);
00160                 pos += rsnie_len;
00161         }
00162         if (mdie) {
00163                 os_memcpy(pos, mdie, mdie_len);
00164                 pos += mdie_len;
00165         }
00166         if (ftie) {
00167                 struct rsn_ftie *_ftie;
00168                 os_memcpy(pos, ftie, ftie_len);
00169                 if (ftie_len < 2 + sizeof(*_ftie)) {
00170                         os_free(buf);
00171                         return -1;
00172                 }
00173                 _ftie = (struct rsn_ftie *) (pos + 2);
00174                 os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
00175                 pos += ftie_len;
00176         }
00177         if (ric) {
00178                 os_memcpy(pos, ric, ric_len);
00179                 pos += ric_len;
00180         }
00181 
00182         wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
00183         if (omac1_aes_128(kck, buf, pos - buf, mic)) {
00184                 os_free(buf);
00185                 return -1;
00186         }
00187 
00188         os_free(buf);
00189 
00190         return 0;
00191 }
00192 #endif /* CONFIG_IEEE80211R */
00193 
00194 
00195 #ifndef CONFIG_NO_WPA2
00196 static int rsn_selector_to_bitfield(const u8 *s)
00197 {
00198         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
00199                 return WPA_CIPHER_NONE;
00200         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
00201                 return WPA_CIPHER_WEP40;
00202         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
00203                 return WPA_CIPHER_TKIP;
00204         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
00205                 return WPA_CIPHER_CCMP;
00206         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
00207                 return WPA_CIPHER_WEP104;
00208 #ifdef CONFIG_IEEE80211W
00209         if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
00210                 return WPA_CIPHER_AES_128_CMAC;
00211 #endif /* CONFIG_IEEE80211W */
00212         return 0;
00213 }
00214 
00215 
00216 static int rsn_key_mgmt_to_bitfield(const u8 *s)
00217 {
00218         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
00219                 return WPA_KEY_MGMT_IEEE8021X;
00220         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
00221                 return WPA_KEY_MGMT_PSK;
00222 #ifdef CONFIG_IEEE80211R
00223         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
00224                 return WPA_KEY_MGMT_FT_IEEE8021X;
00225         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
00226                 return WPA_KEY_MGMT_FT_PSK;
00227 #endif /* CONFIG_IEEE80211R */
00228 #ifdef CONFIG_IEEE80211W
00229         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
00230                 return WPA_KEY_MGMT_IEEE8021X_SHA256;
00231         if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
00232                 return WPA_KEY_MGMT_PSK_SHA256;
00233 #endif /* CONFIG_IEEE80211W */
00234         return 0;
00235 }
00236 #endif /* CONFIG_NO_WPA2 */
00237 
00238 
00247 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
00248                          struct wpa_ie_data *data)
00249 {
00250 #ifndef CONFIG_NO_WPA2
00251         const struct rsn_ie_hdr *hdr;
00252         const u8 *pos;
00253         int left;
00254         int i, count;
00255 
00256         os_memset(data, 0, sizeof(*data));
00257         data->proto = WPA_PROTO_RSN;
00258         data->pairwise_cipher = WPA_CIPHER_CCMP;
00259         data->group_cipher = WPA_CIPHER_CCMP;
00260         data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
00261         data->capabilities = 0;
00262         data->pmkid = NULL;
00263         data->num_pmkid = 0;
00264 #ifdef CONFIG_IEEE80211W
00265         data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
00266 #else /* CONFIG_IEEE80211W */
00267         data->mgmt_group_cipher = 0;
00268 #endif /* CONFIG_IEEE80211W */
00269 
00270         if (rsn_ie_len == 0) {
00271                 /* No RSN IE - fail silently */
00272                 return -1;
00273         }
00274 
00275         if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
00276                 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
00277                            __func__, (unsigned long) rsn_ie_len);
00278                 return -1;
00279         }
00280 
00281         hdr = (const struct rsn_ie_hdr *) rsn_ie;
00282 
00283         if (hdr->elem_id != WLAN_EID_RSN ||
00284             hdr->len != rsn_ie_len - 2 ||
00285             WPA_GET_LE16(hdr->version) != RSN_VERSION) {
00286                 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
00287                            __func__);
00288                 return -2;
00289         }
00290 
00291         pos = (const u8 *) (hdr + 1);
00292         left = rsn_ie_len - sizeof(*hdr);
00293 
00294         if (left >= RSN_SELECTOR_LEN) {
00295                 data->group_cipher = rsn_selector_to_bitfield(pos);
00296 #ifdef CONFIG_IEEE80211W
00297                 if (data->group_cipher == WPA_CIPHER_AES_128_CMAC) {
00298                         wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as group "
00299                                    "cipher", __func__);
00300                         return -1;
00301                 }
00302 #endif /* CONFIG_IEEE80211W */
00303                 pos += RSN_SELECTOR_LEN;
00304                 left -= RSN_SELECTOR_LEN;
00305         } else if (left > 0) {
00306                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
00307                            __func__, left);
00308                 return -3;
00309         }
00310 
00311         if (left >= 2) {
00312                 data->pairwise_cipher = 0;
00313                 count = WPA_GET_LE16(pos);
00314                 pos += 2;
00315                 left -= 2;
00316                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
00317                         wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
00318                                    "count %u left %u", __func__, count, left);
00319                         return -4;
00320                 }
00321                 for (i = 0; i < count; i++) {
00322                         data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
00323                         pos += RSN_SELECTOR_LEN;
00324                         left -= RSN_SELECTOR_LEN;
00325                 }
00326 #ifdef CONFIG_IEEE80211W
00327                 if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
00328                         wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
00329                                    "pairwise cipher", __func__);
00330                         return -1;
00331                 }
00332 #endif /* CONFIG_IEEE80211W */
00333         } else if (left == 1) {
00334                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
00335                            __func__);
00336                 return -5;
00337         }
00338 
00339         if (left >= 2) {
00340                 data->key_mgmt = 0;
00341                 count = WPA_GET_LE16(pos);
00342                 pos += 2;
00343                 left -= 2;
00344                 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
00345                         wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
00346                                    "count %u left %u", __func__, count, left);
00347                         return -6;
00348                 }
00349                 for (i = 0; i < count; i++) {
00350                         data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
00351                         pos += RSN_SELECTOR_LEN;
00352                         left -= RSN_SELECTOR_LEN;
00353                 }
00354         } else if (left == 1) {
00355                 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
00356                            __func__);
00357                 return -7;
00358         }
00359 
00360         if (left >= 2) {
00361                 data->capabilities = WPA_GET_LE16(pos);
00362                 pos += 2;
00363                 left -= 2;
00364         }
00365 
00366         if (left >= 2) {
00367                 data->num_pmkid = WPA_GET_LE16(pos);
00368                 pos += 2;
00369                 left -= 2;
00370                 if (left < (int) data->num_pmkid * PMKID_LEN) {
00371                         wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
00372                                    "(num_pmkid=%lu left=%d)",
00373                                    __func__, (unsigned long) data->num_pmkid,
00374                                    left);
00375                         data->num_pmkid = 0;
00376                         return -9;
00377                 } else {
00378                         data->pmkid = pos;
00379                         pos += data->num_pmkid * PMKID_LEN;
00380                         left -= data->num_pmkid * PMKID_LEN;
00381                 }
00382         }
00383 
00384 #ifdef CONFIG_IEEE80211W
00385         if (left >= 4) {
00386                 data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
00387                 if (data->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
00388                         wpa_printf(MSG_DEBUG, "%s: Unsupported management "
00389                                    "group cipher 0x%x", __func__,
00390                                    data->mgmt_group_cipher);
00391                         return -10;
00392                 }
00393                 pos += RSN_SELECTOR_LEN;
00394                 left -= RSN_SELECTOR_LEN;
00395         }
00396 #endif /* CONFIG_IEEE80211W */
00397 
00398         if (left > 0) {
00399                 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
00400                            __func__, left);
00401         }
00402 
00403         return 0;
00404 #else /* CONFIG_NO_WPA2 */
00405         return -1;
00406 #endif /* CONFIG_NO_WPA2 */
00407 }
00408 
00409 
00410 #ifdef CONFIG_IEEE80211R
00411 
00418 void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
00419                        const u8 *ssid, size_t ssid_len,
00420                        const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
00421                        const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
00422 {
00423         u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
00424                FT_R0KH_ID_MAX_LEN + ETH_ALEN];
00425         u8 *pos, r0_key_data[48], hash[32];
00426         const u8 *addr[2];
00427         size_t len[2];
00428 
00429         /*
00430          * R0-Key-Data = KDF-384(XXKey, "FT-R0",
00431          *                       SSIDlength || SSID || MDID || R0KHlength ||
00432          *                       R0KH-ID || S0KH-ID)
00433          * XXKey is either the second 256 bits of MSK or PSK.
00434          * PMK-R0 = L(R0-Key-Data, 0, 256)
00435          * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
00436          */
00437         if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
00438                 return;
00439         pos = buf;
00440         *pos++ = ssid_len;
00441         os_memcpy(pos, ssid, ssid_len);
00442         pos += ssid_len;
00443         os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
00444         pos += MOBILITY_DOMAIN_ID_LEN;
00445         *pos++ = r0kh_id_len;
00446         os_memcpy(pos, r0kh_id, r0kh_id_len);
00447         pos += r0kh_id_len;
00448         os_memcpy(pos, s0kh_id, ETH_ALEN);
00449         pos += ETH_ALEN;
00450 
00451         sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
00452                    r0_key_data, sizeof(r0_key_data));
00453         os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
00454 
00455         /*
00456          * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
00457          */
00458         addr[0] = (const u8 *) "FT-R0N";
00459         len[0] = 6;
00460         addr[1] = r0_key_data + PMK_LEN;
00461         len[1] = 16;
00462 
00463         sha256_vector(2, addr, len, hash);
00464         os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
00465 }
00466 
00467 
00474 void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
00475                             const u8 *s1kh_id, u8 *pmk_r1_name)
00476 {
00477         u8 hash[32];
00478         const u8 *addr[4];
00479         size_t len[4];
00480 
00481         /*
00482          * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
00483          *                                  R1KH-ID || S1KH-ID))
00484          */
00485         addr[0] = (const u8 *) "FT-R1N";
00486         len[0] = 6;
00487         addr[1] = pmk_r0_name;
00488         len[1] = WPA_PMK_NAME_LEN;
00489         addr[2] = r1kh_id;
00490         len[2] = FT_R1KH_ID_LEN;
00491         addr[3] = s1kh_id;
00492         len[3] = ETH_ALEN;
00493 
00494         sha256_vector(4, addr, len, hash);
00495         os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
00496 }
00497 
00498 
00505 void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
00506                        const u8 *r1kh_id, const u8 *s1kh_id,
00507                        u8 *pmk_r1, u8 *pmk_r1_name)
00508 {
00509         u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
00510         u8 *pos;
00511 
00512         /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
00513         pos = buf;
00514         os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
00515         pos += FT_R1KH_ID_LEN;
00516         os_memcpy(pos, s1kh_id, ETH_ALEN);
00517         pos += ETH_ALEN;
00518 
00519         sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
00520 
00521         wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
00522 }
00523 
00524 
00531 void wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
00532                        const u8 *sta_addr, const u8 *bssid,
00533                        const u8 *pmk_r1_name,
00534                        u8 *ptk, size_t ptk_len, u8 *ptk_name)
00535 {
00536         u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
00537         u8 *pos, hash[32];
00538         const u8 *addr[6];
00539         size_t len[6];
00540 
00541         /*
00542          * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
00543          *                  BSSID || STA-ADDR)
00544          */
00545         pos = buf;
00546         os_memcpy(pos, snonce, WPA_NONCE_LEN);
00547         pos += WPA_NONCE_LEN;
00548         os_memcpy(pos, anonce, WPA_NONCE_LEN);
00549         pos += WPA_NONCE_LEN;
00550         os_memcpy(pos, bssid, ETH_ALEN);
00551         pos += ETH_ALEN;
00552         os_memcpy(pos, sta_addr, ETH_ALEN);
00553         pos += ETH_ALEN;
00554 
00555         sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, ptk, ptk_len);
00556 
00557         /*
00558          * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
00559          *                                ANonce || BSSID || STA-ADDR))
00560          */
00561         addr[0] = pmk_r1_name;
00562         len[0] = WPA_PMK_NAME_LEN;
00563         addr[1] = (const u8 *) "FT-PTKN";
00564         len[1] = 7;
00565         addr[2] = snonce;
00566         len[2] = WPA_NONCE_LEN;
00567         addr[3] = anonce;
00568         len[3] = WPA_NONCE_LEN;
00569         addr[4] = bssid;
00570         len[4] = ETH_ALEN;
00571         addr[5] = sta_addr;
00572         len[5] = ETH_ALEN;
00573 
00574         sha256_vector(6, addr, len, hash);
00575         os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
00576 }
00577 
00578 #endif /* CONFIG_IEEE80211R */
00579 
00580 
00594 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
00595                u8 *pmkid, int use_sha256)
00596 {
00597         char *title = "PMK Name";
00598         const u8 *addr[3];
00599         const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
00600         unsigned char hash[SHA256_MAC_LEN];
00601 
00602         addr[0] = (u8 *) title;
00603         addr[1] = aa;
00604         addr[2] = spa;
00605 
00606 #ifdef CONFIG_IEEE80211W
00607         if (use_sha256)
00608                 hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
00609         else
00610 #endif /* CONFIG_IEEE80211W */
00611                 hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
00612         os_memcpy(pmkid, hash, PMKID_LEN);
00613 }
00614 
00615 
00622 const char * wpa_cipher_txt(int cipher)
00623 {
00624         switch (cipher) {
00625         case WPA_CIPHER_NONE:
00626                 return "NONE";
00627         case WPA_CIPHER_WEP40:
00628                 return "WEP-40";
00629         case WPA_CIPHER_WEP104:
00630                 return "WEP-104";
00631         case WPA_CIPHER_TKIP:
00632                 return "TKIP";
00633         case WPA_CIPHER_CCMP:
00634                 return "CCMP";
00635         case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
00636                 return "CCMP+TKIP";
00637         default:
00638                 return "UNKNOWN";
00639         }
00640 }
00641 
00642 
00650 const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
00651 {
00652         switch (key_mgmt) {
00653         case WPA_KEY_MGMT_IEEE8021X:
00654                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
00655                         return "WPA2+WPA/IEEE 802.1X/EAP";
00656                 return proto == WPA_PROTO_RSN ?
00657                         "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
00658         case WPA_KEY_MGMT_PSK:
00659                 if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
00660                         return "WPA2-PSK+WPA-PSK";
00661                 return proto == WPA_PROTO_RSN ?
00662                         "WPA2-PSK" : "WPA-PSK";
00663         case WPA_KEY_MGMT_NONE:
00664                 return "NONE";
00665         case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
00666                 return "IEEE 802.1X (no WPA)";
00667 #ifdef CONFIG_IEEE80211R
00668         case WPA_KEY_MGMT_FT_IEEE8021X:
00669                 return "FT-EAP";
00670         case WPA_KEY_MGMT_FT_PSK:
00671                 return "FT-PSK";
00672 #endif /* CONFIG_IEEE80211R */
00673 #ifdef CONFIG_IEEE80211W
00674         case WPA_KEY_MGMT_IEEE8021X_SHA256:
00675                 return "WPA2-EAP-SHA256";
00676         case WPA_KEY_MGMT_PSK_SHA256:
00677                 return "WPA2-PSK-SHA256";
00678 #endif /* CONFIG_IEEE80211W */
00679         default:
00680                 return "UNKNOWN";
00681         }
00682 }
00683 
 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