00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "wpa.h"
00020 #include "pmksa_cache.h"
00021 #include "ieee802_11_defs.h"
00022 #include "wpa_i.h"
00023 #include "wpa_ie.h"
00024
00025
00026 static int wpa_selector_to_bitfield(const u8 *s)
00027 {
00028 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
00029 return WPA_CIPHER_NONE;
00030 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
00031 return WPA_CIPHER_WEP40;
00032 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
00033 return WPA_CIPHER_TKIP;
00034 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
00035 return WPA_CIPHER_CCMP;
00036 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
00037 return WPA_CIPHER_WEP104;
00038 return 0;
00039 }
00040
00041
00042 static int wpa_key_mgmt_to_bitfield(const u8 *s)
00043 {
00044 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
00045 return WPA_KEY_MGMT_IEEE8021X;
00046 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
00047 return WPA_KEY_MGMT_PSK;
00048 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
00049 return WPA_KEY_MGMT_WPA_NONE;
00050 return 0;
00051 }
00052
00053
00054 static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
00055 struct wpa_ie_data *data)
00056 {
00057 const struct wpa_ie_hdr *hdr;
00058 const u8 *pos;
00059 int left;
00060 int i, count;
00061
00062 os_memset(data, 0, sizeof(*data));
00063 data->proto = WPA_PROTO_WPA;
00064 data->pairwise_cipher = WPA_CIPHER_TKIP;
00065 data->group_cipher = WPA_CIPHER_TKIP;
00066 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
00067 data->capabilities = 0;
00068 data->pmkid = NULL;
00069 data->num_pmkid = 0;
00070 data->mgmt_group_cipher = 0;
00071
00072 if (wpa_ie_len == 0) {
00073
00074 return -1;
00075 }
00076
00077 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
00078 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
00079 __func__, (unsigned long) wpa_ie_len);
00080 return -1;
00081 }
00082
00083 hdr = (const struct wpa_ie_hdr *) wpa_ie;
00084
00085 if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
00086 hdr->len != wpa_ie_len - 2 ||
00087 RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
00088 WPA_GET_LE16(hdr->version) != WPA_VERSION) {
00089 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
00090 __func__);
00091 return -1;
00092 }
00093
00094 pos = (const u8 *) (hdr + 1);
00095 left = wpa_ie_len - sizeof(*hdr);
00096
00097 if (left >= WPA_SELECTOR_LEN) {
00098 data->group_cipher = wpa_selector_to_bitfield(pos);
00099 pos += WPA_SELECTOR_LEN;
00100 left -= WPA_SELECTOR_LEN;
00101 } else if (left > 0) {
00102 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
00103 __func__, left);
00104 return -1;
00105 }
00106
00107 if (left >= 2) {
00108 data->pairwise_cipher = 0;
00109 count = WPA_GET_LE16(pos);
00110 pos += 2;
00111 left -= 2;
00112 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00113 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
00114 "count %u left %u", __func__, count, left);
00115 return -1;
00116 }
00117 for (i = 0; i < count; i++) {
00118 data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
00119 pos += WPA_SELECTOR_LEN;
00120 left -= WPA_SELECTOR_LEN;
00121 }
00122 } else if (left == 1) {
00123 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
00124 __func__);
00125 return -1;
00126 }
00127
00128 if (left >= 2) {
00129 data->key_mgmt = 0;
00130 count = WPA_GET_LE16(pos);
00131 pos += 2;
00132 left -= 2;
00133 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
00134 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
00135 "count %u left %u", __func__, count, left);
00136 return -1;
00137 }
00138 for (i = 0; i < count; i++) {
00139 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
00140 pos += WPA_SELECTOR_LEN;
00141 left -= WPA_SELECTOR_LEN;
00142 }
00143 } else if (left == 1) {
00144 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
00145 __func__);
00146 return -1;
00147 }
00148
00149 if (left >= 2) {
00150 data->capabilities = WPA_GET_LE16(pos);
00151 pos += 2;
00152 left -= 2;
00153 }
00154
00155 if (left > 0) {
00156 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
00157 __func__, left);
00158 }
00159
00160 return 0;
00161 }
00162
00163
00174 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
00175 struct wpa_ie_data *data)
00176 {
00177 if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
00178 return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
00179 else
00180 return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
00181 }
00182
00183
00184 static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
00185 int pairwise_cipher, int group_cipher,
00186 int key_mgmt)
00187 {
00188 u8 *pos;
00189 struct wpa_ie_hdr *hdr;
00190
00191 if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN +
00192 2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN)
00193 return -1;
00194
00195 hdr = (struct wpa_ie_hdr *) wpa_ie;
00196 hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
00197 RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
00198 WPA_PUT_LE16(hdr->version, WPA_VERSION);
00199 pos = (u8 *) (hdr + 1);
00200
00201 if (group_cipher == WPA_CIPHER_CCMP) {
00202 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00203 } else if (group_cipher == WPA_CIPHER_TKIP) {
00204 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00205 } else if (group_cipher == WPA_CIPHER_WEP104) {
00206 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104);
00207 } else if (group_cipher == WPA_CIPHER_WEP40) {
00208 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40);
00209 } else {
00210 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00211 group_cipher);
00212 return -1;
00213 }
00214 pos += WPA_SELECTOR_LEN;
00215
00216 *pos++ = 1;
00217 *pos++ = 0;
00218 if (pairwise_cipher == WPA_CIPHER_CCMP) {
00219 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
00220 } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00221 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
00222 } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00223 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
00224 } else {
00225 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00226 pairwise_cipher);
00227 return -1;
00228 }
00229 pos += WPA_SELECTOR_LEN;
00230
00231 *pos++ = 1;
00232 *pos++ = 0;
00233 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00234 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
00235 } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00236 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00237 } else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
00238 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE);
00239 } else {
00240 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00241 key_mgmt);
00242 return -1;
00243 }
00244 pos += WPA_SELECTOR_LEN;
00245
00246
00247
00248 hdr->len = (pos - wpa_ie) - 2;
00249
00250 WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
00251
00252 return pos - wpa_ie;
00253 }
00254
00255
00256 static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
00257 int pairwise_cipher, int group_cipher,
00258 int key_mgmt, int mgmt_group_cipher,
00259 struct wpa_sm *sm)
00260 {
00261 #ifndef CONFIG_NO_WPA2
00262 u8 *pos;
00263 struct rsn_ie_hdr *hdr;
00264 u16 capab;
00265
00266 if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
00267 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
00268 (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) {
00269 wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)",
00270 (unsigned long) rsn_ie_len);
00271 return -1;
00272 }
00273
00274 hdr = (struct rsn_ie_hdr *) rsn_ie;
00275 hdr->elem_id = WLAN_EID_RSN;
00276 WPA_PUT_LE16(hdr->version, RSN_VERSION);
00277 pos = (u8 *) (hdr + 1);
00278
00279 if (group_cipher == WPA_CIPHER_CCMP) {
00280 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00281 } else if (group_cipher == WPA_CIPHER_TKIP) {
00282 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00283 } else if (group_cipher == WPA_CIPHER_WEP104) {
00284 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104);
00285 } else if (group_cipher == WPA_CIPHER_WEP40) {
00286 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40);
00287 } else {
00288 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
00289 group_cipher);
00290 return -1;
00291 }
00292 pos += RSN_SELECTOR_LEN;
00293
00294 *pos++ = 1;
00295 *pos++ = 0;
00296 if (pairwise_cipher == WPA_CIPHER_CCMP) {
00297 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
00298 } else if (pairwise_cipher == WPA_CIPHER_TKIP) {
00299 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
00300 } else if (pairwise_cipher == WPA_CIPHER_NONE) {
00301 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
00302 } else {
00303 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
00304 pairwise_cipher);
00305 return -1;
00306 }
00307 pos += RSN_SELECTOR_LEN;
00308
00309 *pos++ = 1;
00310 *pos++ = 0;
00311 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
00312 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
00313 } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
00314 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
00315 #ifdef CONFIG_IEEE80211R
00316 } else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
00317 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
00318 } else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
00319 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
00320 #endif
00321 #ifdef CONFIG_IEEE80211W
00322 } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
00323 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
00324 } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
00325 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
00326 #endif
00327 } else {
00328 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
00329 key_mgmt);
00330 return -1;
00331 }
00332 pos += RSN_SELECTOR_LEN;
00333
00334
00335 capab = 0;
00336 #ifdef CONFIG_IEEE80211W
00337 if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC)
00338 capab |= WPA_CAPABILITY_MFPC;
00339 #endif
00340 WPA_PUT_LE16(pos, capab);
00341 pos += 2;
00342
00343 if (sm->cur_pmksa) {
00344
00345 *pos++ = 1;
00346 *pos++ = 0;
00347
00348 os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
00349 pos += PMKID_LEN;
00350 }
00351
00352 #ifdef CONFIG_IEEE80211W
00353 if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
00354 if (!sm->cur_pmksa) {
00355
00356 WPA_PUT_LE16(pos, 0);
00357 pos += 2;
00358 }
00359
00360
00361 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
00362 pos += RSN_SELECTOR_LEN;
00363 }
00364 #endif
00365
00366 hdr->len = (pos - rsn_ie) - 2;
00367
00368 WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
00369
00370 return pos - rsn_ie;
00371 #else
00372 return -1;
00373 #endif
00374 }
00375
00376
00385 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
00386 {
00387 if (sm->proto == WPA_PROTO_RSN)
00388 return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
00389 sm->pairwise_cipher,
00390 sm->group_cipher,
00391 sm->key_mgmt, sm->mgmt_group_cipher,
00392 sm);
00393 else
00394 return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
00395 sm->pairwise_cipher,
00396 sm->group_cipher,
00397 sm->key_mgmt);
00398 }
00399
00400
00409 static int wpa_parse_generic(const u8 *pos, const u8 *end,
00410 struct wpa_eapol_ie_parse *ie)
00411 {
00412 if (pos[1] == 0)
00413 return 1;
00414
00415 if (pos[1] >= 6 &&
00416 RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
00417 pos[2 + WPA_SELECTOR_LEN] == 1 &&
00418 pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
00419 ie->wpa_ie = pos;
00420 ie->wpa_ie_len = pos[1] + 2;
00421 return 0;
00422 }
00423
00424 if (pos + 1 + RSN_SELECTOR_LEN < end &&
00425 pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
00426 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
00427 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
00428 return 0;
00429 }
00430
00431 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00432 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
00433 ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
00434 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
00435 return 0;
00436 }
00437
00438 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00439 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
00440 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
00441 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
00442 return 0;
00443 }
00444
00445 #ifdef CONFIG_PEERKEY
00446 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00447 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
00448 ie->smk = pos + 2 + RSN_SELECTOR_LEN;
00449 ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
00450 return 0;
00451 }
00452
00453 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00454 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
00455 ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
00456 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
00457 return 0;
00458 }
00459
00460 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00461 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
00462 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
00463 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
00464 return 0;
00465 }
00466
00467 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00468 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
00469 ie->error = pos + 2 + RSN_SELECTOR_LEN;
00470 ie->error_len = pos[1] - RSN_SELECTOR_LEN;
00471 return 0;
00472 }
00473 #endif
00474
00475 #ifdef CONFIG_IEEE80211W
00476 if (pos[1] > RSN_SELECTOR_LEN + 2 &&
00477 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
00478 ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
00479 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
00480 return 0;
00481 }
00482 #endif
00483
00484 return 0;
00485 }
00486
00487
00496 int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
00497 struct wpa_eapol_ie_parse *ie)
00498 {
00499 const u8 *pos, *end;
00500 int ret = 0;
00501
00502 os_memset(ie, 0, sizeof(*ie));
00503 for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
00504 if (pos[0] == 0xdd &&
00505 ((pos == buf + len - 1) || pos[1] == 0)) {
00506
00507 break;
00508 }
00509 if (pos + 2 + pos[1] > end) {
00510 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
00511 "underflow (ie=%d len=%d pos=%d)",
00512 pos[0], pos[1], (int) (pos - buf));
00513 wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
00514 buf, len);
00515 ret = -1;
00516 break;
00517 }
00518 if (*pos == WLAN_EID_RSN) {
00519 ie->rsn_ie = pos;
00520 ie->rsn_ie_len = pos[1] + 2;
00521 #ifdef CONFIG_IEEE80211R
00522 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
00523 ie->mdie = pos;
00524 ie->mdie_len = pos[1] + 2;
00525 #endif
00526 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
00527 ret = wpa_parse_generic(pos, end, ie);
00528 if (ret < 0)
00529 break;
00530 if (ret > 0) {
00531 ret = 0;
00532 break;
00533 }
00534 } else {
00535 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
00536 "Key Data IE", pos, 2 + pos[1]);
00537 }
00538 }
00539
00540 return ret;
00541 }
00542