1 /* 2 * wpa_supplicant - WPA/RSN IE and KDE processing 3 * Copyright (c) 2003-2008, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "wpa.h" 19 #include "pmksa_cache.h" 20 #include "ieee802_11_defs.h" 21 #include "wpa_i.h" 22 #include "wpa_ie.h" 23 24 25 static int wpa_selector_to_bitfield(const u8 *s) 26 { 27 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE) 28 return WPA_CIPHER_NONE; 29 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40) 30 return WPA_CIPHER_WEP40; 31 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP) 32 return WPA_CIPHER_TKIP; 33 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP) 34 return WPA_CIPHER_CCMP; 35 if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104) 36 return WPA_CIPHER_WEP104; 37 return 0; 38 } 39 40 41 static int wpa_key_mgmt_to_bitfield(const u8 *s) 42 { 43 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X) 44 return WPA_KEY_MGMT_IEEE8021X; 45 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X) 46 return WPA_KEY_MGMT_PSK; 47 if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE) 48 return WPA_KEY_MGMT_WPA_NONE; 49 return 0; 50 } 51 52 53 static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, 54 struct wpa_ie_data *data) 55 { 56 const struct wpa_ie_hdr *hdr; 57 const u8 *pos; 58 int left; 59 int i, count; 60 61 os_memset(data, 0, sizeof(*data)); 62 data->proto = WPA_PROTO_WPA; 63 data->pairwise_cipher = WPA_CIPHER_TKIP; 64 data->group_cipher = WPA_CIPHER_TKIP; 65 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; 66 data->capabilities = 0; 67 data->pmkid = NULL; 68 data->num_pmkid = 0; 69 data->mgmt_group_cipher = 0; 70 71 if (wpa_ie_len == 0) { 72 /* No WPA IE - fail silently */ 73 return -1; 74 } 75 76 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) { 77 wpa_printf(MSG_DEBUG, "%s: ie len too short %lu", 78 __func__, (unsigned long) wpa_ie_len); 79 return -1; 80 } 81 82 hdr = (const struct wpa_ie_hdr *) wpa_ie; 83 84 if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC || 85 hdr->len != wpa_ie_len - 2 || 86 RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE || 87 WPA_GET_LE16(hdr->version) != WPA_VERSION) { 88 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", 89 __func__); 90 return -1; 91 } 92 93 pos = (const u8 *) (hdr + 1); 94 left = wpa_ie_len - sizeof(*hdr); 95 96 if (left >= WPA_SELECTOR_LEN) { 97 data->group_cipher = wpa_selector_to_bitfield(pos); 98 pos += WPA_SELECTOR_LEN; 99 left -= WPA_SELECTOR_LEN; 100 } else if (left > 0) { 101 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", 102 __func__, left); 103 return -1; 104 } 105 106 if (left >= 2) { 107 data->pairwise_cipher = 0; 108 count = WPA_GET_LE16(pos); 109 pos += 2; 110 left -= 2; 111 if (count == 0 || left < count * WPA_SELECTOR_LEN) { 112 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " 113 "count %u left %u", __func__, count, left); 114 return -1; 115 } 116 for (i = 0; i < count; i++) { 117 data->pairwise_cipher |= wpa_selector_to_bitfield(pos); 118 pos += WPA_SELECTOR_LEN; 119 left -= WPA_SELECTOR_LEN; 120 } 121 } else if (left == 1) { 122 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", 123 __func__); 124 return -1; 125 } 126 127 if (left >= 2) { 128 data->key_mgmt = 0; 129 count = WPA_GET_LE16(pos); 130 pos += 2; 131 left -= 2; 132 if (count == 0 || left < count * WPA_SELECTOR_LEN) { 133 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " 134 "count %u left %u", __func__, count, left); 135 return -1; 136 } 137 for (i = 0; i < count; i++) { 138 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); 139 pos += WPA_SELECTOR_LEN; 140 left -= WPA_SELECTOR_LEN; 141 } 142 } else if (left == 1) { 143 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", 144 __func__); 145 return -1; 146 } 147 148 if (left >= 2) { 149 data->capabilities = WPA_GET_LE16(pos); 150 pos += 2; 151 left -= 2; 152 } 153 154 if (left > 0) { 155 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored", 156 __func__, left); 157 } 158 159 return 0; 160 } 161 162 163 /** 164 * wpa_parse_wpa_ie - Parse WPA/RSN IE 165 * @wpa_ie: Pointer to WPA or RSN IE 166 * @wpa_ie_len: Length of the WPA/RSN IE 167 * @data: Pointer to data area for parsing results 168 * Returns: 0 on success, -1 on failure 169 * 170 * Parse the contents of WPA or RSN IE and write the parsed data into data. 171 */ 172 int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, 173 struct wpa_ie_data *data) 174 { 175 if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN) 176 return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); 177 else 178 return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); 179 } 180 181 182 static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len, 183 int pairwise_cipher, int group_cipher, 184 int key_mgmt) 185 { 186 u8 *pos; 187 struct wpa_ie_hdr *hdr; 188 189 if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN + 190 2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN) 191 return -1; 192 193 hdr = (struct wpa_ie_hdr *) wpa_ie; 194 hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC; 195 RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE); 196 WPA_PUT_LE16(hdr->version, WPA_VERSION); 197 pos = (u8 *) (hdr + 1); 198 199 if (group_cipher == WPA_CIPHER_CCMP) { 200 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); 201 } else if (group_cipher == WPA_CIPHER_TKIP) { 202 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); 203 } else if (group_cipher == WPA_CIPHER_WEP104) { 204 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104); 205 } else if (group_cipher == WPA_CIPHER_WEP40) { 206 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40); 207 } else { 208 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).", 209 group_cipher); 210 return -1; 211 } 212 pos += WPA_SELECTOR_LEN; 213 214 *pos++ = 1; 215 *pos++ = 0; 216 if (pairwise_cipher == WPA_CIPHER_CCMP) { 217 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); 218 } else if (pairwise_cipher == WPA_CIPHER_TKIP) { 219 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); 220 } else if (pairwise_cipher == WPA_CIPHER_NONE) { 221 RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE); 222 } else { 223 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).", 224 pairwise_cipher); 225 return -1; 226 } 227 pos += WPA_SELECTOR_LEN; 228 229 *pos++ = 1; 230 *pos++ = 0; 231 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) { 232 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X); 233 } else if (key_mgmt == WPA_KEY_MGMT_PSK) { 234 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X); 235 } else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) { 236 RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE); 237 } else { 238 wpa_printf(MSG_WARNING, "Invalid key management type (%d).", 239 key_mgmt); 240 return -1; 241 } 242 pos += WPA_SELECTOR_LEN; 243 244 /* WPA Capabilities; use defaults, so no need to include it */ 245 246 hdr->len = (pos - wpa_ie) - 2; 247 248 WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len); 249 250 return pos - wpa_ie; 251 } 252 253 254 static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len, 255 int pairwise_cipher, int group_cipher, 256 int key_mgmt, int mgmt_group_cipher, 257 struct wpa_sm *sm) 258 { 259 #ifndef CONFIG_NO_WPA2 260 u8 *pos; 261 struct rsn_ie_hdr *hdr; 262 u16 capab; 263 264 if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN + 265 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 + 266 (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) { 267 wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)", 268 (unsigned long) rsn_ie_len); 269 return -1; 270 } 271 272 hdr = (struct rsn_ie_hdr *) rsn_ie; 273 hdr->elem_id = WLAN_EID_RSN; 274 WPA_PUT_LE16(hdr->version, RSN_VERSION); 275 pos = (u8 *) (hdr + 1); 276 277 if (group_cipher == WPA_CIPHER_CCMP) { 278 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 279 } else if (group_cipher == WPA_CIPHER_TKIP) { 280 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 281 } else if (group_cipher == WPA_CIPHER_WEP104) { 282 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104); 283 } else if (group_cipher == WPA_CIPHER_WEP40) { 284 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40); 285 } else { 286 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).", 287 group_cipher); 288 return -1; 289 } 290 pos += RSN_SELECTOR_LEN; 291 292 *pos++ = 1; 293 *pos++ = 0; 294 if (pairwise_cipher == WPA_CIPHER_CCMP) { 295 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 296 } else if (pairwise_cipher == WPA_CIPHER_TKIP) { 297 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 298 } else if (pairwise_cipher == WPA_CIPHER_NONE) { 299 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE); 300 } else { 301 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).", 302 pairwise_cipher); 303 return -1; 304 } 305 pos += RSN_SELECTOR_LEN; 306 307 *pos++ = 1; 308 *pos++ = 0; 309 if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) { 310 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X); 311 } else if (key_mgmt == WPA_KEY_MGMT_PSK) { 312 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X); 313 #ifdef CONFIG_IEEE80211R 314 } else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) { 315 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); 316 } else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) { 317 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); 318 #endif /* CONFIG_IEEE80211R */ 319 #ifdef CONFIG_IEEE80211W 320 } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) { 321 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256); 322 } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) { 323 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256); 324 #endif /* CONFIG_IEEE80211W */ 325 } else { 326 wpa_printf(MSG_WARNING, "Invalid key management type (%d).", 327 key_mgmt); 328 return -1; 329 } 330 pos += RSN_SELECTOR_LEN; 331 332 /* RSN Capabilities */ 333 capab = 0; 334 #ifdef CONFIG_IEEE80211W 335 if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) 336 capab |= WPA_CAPABILITY_MFPC; 337 #endif /* CONFIG_IEEE80211W */ 338 WPA_PUT_LE16(pos, capab); 339 pos += 2; 340 341 if (sm->cur_pmksa) { 342 /* PMKID Count (2 octets, little endian) */ 343 *pos++ = 1; 344 *pos++ = 0; 345 /* PMKID */ 346 os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN); 347 pos += PMKID_LEN; 348 } 349 350 #ifdef CONFIG_IEEE80211W 351 if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) { 352 if (!sm->cur_pmksa) { 353 /* PMKID Count */ 354 WPA_PUT_LE16(pos, 0); 355 pos += 2; 356 } 357 358 /* Management Group Cipher Suite */ 359 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 360 pos += RSN_SELECTOR_LEN; 361 } 362 #endif /* CONFIG_IEEE80211W */ 363 364 hdr->len = (pos - rsn_ie) - 2; 365 366 WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len); 367 368 return pos - rsn_ie; 369 #else /* CONFIG_NO_WPA2 */ 370 return -1; 371 #endif /* CONFIG_NO_WPA2 */ 372 } 373 374 375 /** 376 * wpa_gen_wpa_ie - Generate WPA/RSN IE based on current security policy 377 * @sm: Pointer to WPA state machine data from wpa_sm_init() 378 * @wpa_ie: Pointer to memory area for the generated WPA/RSN IE 379 * @wpa_ie_len: Maximum length of the generated WPA/RSN IE 380 * Returns: Length of the generated WPA/RSN IE or -1 on failure 381 */ 382 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len) 383 { 384 if (sm->proto == WPA_PROTO_RSN) 385 return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len, 386 sm->pairwise_cipher, 387 sm->group_cipher, 388 sm->key_mgmt, sm->mgmt_group_cipher, 389 sm); 390 else 391 return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len, 392 sm->pairwise_cipher, 393 sm->group_cipher, 394 sm->key_mgmt); 395 } 396 397 398 /** 399 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs 400 * @pos: Pointer to the IE header 401 * @end: Pointer to the end of the Key Data buffer 402 * @ie: Pointer to parsed IE data 403 * Returns: 0 on success, 1 if end mark is found, -1 on failure 404 */ 405 static int wpa_parse_generic(const u8 *pos, const u8 *end, 406 struct wpa_eapol_ie_parse *ie) 407 { 408 if (pos[1] == 0) 409 return 1; 410 411 if (pos[1] >= 6 && 412 RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE && 413 pos[2 + WPA_SELECTOR_LEN] == 1 && 414 pos[2 + WPA_SELECTOR_LEN + 1] == 0) { 415 ie->wpa_ie = pos; 416 ie->wpa_ie_len = pos[1] + 2; 417 return 0; 418 } 419 420 if (pos + 1 + RSN_SELECTOR_LEN < end && 421 pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN && 422 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) { 423 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN; 424 return 0; 425 } 426 427 if (pos[1] > RSN_SELECTOR_LEN + 2 && 428 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) { 429 ie->gtk = pos + 2 + RSN_SELECTOR_LEN; 430 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN; 431 return 0; 432 } 433 434 if (pos[1] > RSN_SELECTOR_LEN + 2 && 435 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) { 436 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN; 437 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN; 438 return 0; 439 } 440 441 #ifdef CONFIG_PEERKEY 442 if (pos[1] > RSN_SELECTOR_LEN + 2 && 443 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) { 444 ie->smk = pos + 2 + RSN_SELECTOR_LEN; 445 ie->smk_len = pos[1] - RSN_SELECTOR_LEN; 446 return 0; 447 } 448 449 if (pos[1] > RSN_SELECTOR_LEN + 2 && 450 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) { 451 ie->nonce = pos + 2 + RSN_SELECTOR_LEN; 452 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN; 453 return 0; 454 } 455 456 if (pos[1] > RSN_SELECTOR_LEN + 2 && 457 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) { 458 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN; 459 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN; 460 return 0; 461 } 462 463 if (pos[1] > RSN_SELECTOR_LEN + 2 && 464 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) { 465 ie->error = pos + 2 + RSN_SELECTOR_LEN; 466 ie->error_len = pos[1] - RSN_SELECTOR_LEN; 467 return 0; 468 } 469 #endif /* CONFIG_PEERKEY */ 470 471 #ifdef CONFIG_IEEE80211W 472 if (pos[1] > RSN_SELECTOR_LEN + 2 && 473 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) { 474 ie->igtk = pos + 2 + RSN_SELECTOR_LEN; 475 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN; 476 return 0; 477 } 478 #endif /* CONFIG_IEEE80211W */ 479 480 return 0; 481 } 482 483 484 /** 485 * wpa_supplicant_parse_ies - Parse EAPOL-Key Key Data IEs 486 * @buf: Pointer to the Key Data buffer 487 * @len: Key Data Length 488 * @ie: Pointer to parsed IE data 489 * Returns: 0 on success, -1 on failure 490 */ 491 int wpa_supplicant_parse_ies(const u8 *buf, size_t len, 492 struct wpa_eapol_ie_parse *ie) 493 { 494 const u8 *pos, *end; 495 int ret = 0; 496 497 os_memset(ie, 0, sizeof(*ie)); 498 for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) { 499 if (pos[0] == 0xdd && 500 ((pos == buf + len - 1) || pos[1] == 0)) { 501 /* Ignore padding */ 502 break; 503 } 504 if (pos + 2 + pos[1] > end) { 505 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data " 506 "underflow (ie=%d len=%d pos=%d)", 507 pos[0], pos[1], (int) (pos - buf)); 508 wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", 509 buf, len); 510 ret = -1; 511 break; 512 } 513 if (*pos == WLAN_EID_RSN) { 514 ie->rsn_ie = pos; 515 ie->rsn_ie_len = pos[1] + 2; 516 #ifdef CONFIG_IEEE80211R 517 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) { 518 ie->mdie = pos; 519 ie->mdie_len = pos[1] + 2; 520 #endif /* CONFIG_IEEE80211R */ 521 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) { 522 ret = wpa_parse_generic(pos, end, ie); 523 if (ret < 0) 524 break; 525 if (ret > 0) { 526 ret = 0; 527 break; 528 } 529 } else { 530 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key " 531 "Key Data IE", pos, 2 + pos[1]); 532 } 533 } 534 535 return ret; 536 } 537