wpa_auth_ie.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
14ef8dd6e8736097bf9e3c387139c668565d89dcaChris Lattner/* 24ef8dd6e8736097bf9e3c387139c668565d89dcaChris Lattner * hostapd - WPA/RSN IE and KDE definitions 3392cf91c7b3270a9b27baa3c5b21a836f3330d98Sebastian Redl * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4392cf91c7b3270a9b27baa3c5b21a836f3330d98Sebastian Redl * 54ef8dd6e8736097bf9e3c387139c668565d89dcaChris Lattner * This program is free software; you can redistribute it and/or modify 64ef8dd6e8736097bf9e3c387139c668565d89dcaChris Lattner * it under the terms of the GNU General Public License version 2 as 7f6c717c3dca839dcd189b4a6fa46c8fe7a8bec1dDouglas Gregor * published by the Free Software Foundation. 8f6c717c3dca839dcd189b4a6fa46c8fe7a8bec1dDouglas Gregor * 9f6c717c3dca839dcd189b4a6fa46c8fe7a8bec1dDouglas Gregor * Alternatively, this software may be distributed under the terms of BSD 104ef8dd6e8736097bf9e3c387139c668565d89dcaChris Lattner * license. 114cc627111453b75519d5130b57e06256da7b00e8Chris Lattner * 124cc627111453b75519d5130b57e06256da7b00e8Chris Lattner * See README and COPYING for more details. 134cc627111453b75519d5130b57e06256da7b00e8Chris Lattner */ 144cc627111453b75519d5130b57e06256da7b00e8Chris Lattner 15d411e04db18f7d07a889d51086861b23cbe05518Chris Lattner#include "utils/includes.h" 16d411e04db18f7d07a889d51086861b23cbe05518Chris Lattner 17d411e04db18f7d07a889d51086861b23cbe05518Chris Lattner#include "utils/common.h" 18d411e04db18f7d07a889d51086861b23cbe05518Chris Lattner#include "common/ieee802_11_defs.h" 19d411e04db18f7d07a889d51086861b23cbe05518Chris Lattner#include "eapol_auth/eapol_auth_sm.h" 20a312ce2bdaaff62f21d560bad6cb0519f613d334Eli Friedman#include "ap_config.h" 21a312ce2bdaaff62f21d560bad6cb0519f613d334Eli Friedman#include "ieee802_11.h" 229f4d86389f99c5d66664382add340a2ea19ad134Sebastian Redl#include "wpa_auth.h" 231f6f54be86a514d531ec231fd837858a43cfe72eChris Lattner#include "pmksa_cache_auth.h" 24a312ce2bdaaff62f21d560bad6cb0519f613d334Eli Friedman#include "wpa_auth_ie.h" 25be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner#include "wpa_auth_i.h" 26be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner 27be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner 28be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner#ifdef CONFIG_RSN_TESTING 29be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattnerint rsn_testing = 0; 30be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner#endif /* CONFIG_RSN_TESTING */ 31be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner 32be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner 33be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattnerstatic int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len) 34be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner{ 35be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner struct wpa_ie_hdr *hdr; 36be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner int num_suites; 37be34ac67225fc4af6134c7f3507c777cceeec867Chris Lattner u8 *pos, *count; 3897c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman 3997c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman hdr = (struct wpa_ie_hdr *) buf; 4097c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC; 4197c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE); 4297c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman WPA_PUT_LE16(hdr->version, WPA_VERSION); 4397c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman pos = (u8 *) (hdr + 1); 4497c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman 4597c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman if (conf->wpa_group == WPA_CIPHER_CCMP) { 46d8803632d248a360a040ff03eff1162988058036Chris Lattner RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); 4797c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman } else if (conf->wpa_group == WPA_CIPHER_TKIP) { 4897c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); 4997c0a391138d20e1066174a9cfa92860fb06e5a1Eli Friedman } else if (conf->wpa_group == WPA_CIPHER_WEP104) { 50f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104); 51f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman } else if (conf->wpa_group == WPA_CIPHER_WEP40) { 52f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40); 53f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman } else { 54f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", 55f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman conf->wpa_group); 56f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman return -1; 57f8f873deef78de611dd793a1e1201bef0d5a54a3Eli Friedman } 58d5bac5704768606c3182dcc1386de12b3944601bChris Lattner pos += WPA_SELECTOR_LEN; 59d5bac5704768606c3182dcc1386de12b3944601bChris Lattner 60d5bac5704768606c3182dcc1386de12b3944601bChris Lattner num_suites = 0; 61d5bac5704768606c3182dcc1386de12b3944601bChris Lattner count = pos; 621e465df22f312a3661d70fc15b1a55dc97ebfce8Daniel Dunbar pos += 2; 631e465df22f312a3661d70fc15b1a55dc97ebfce8Daniel Dunbar 641e465df22f312a3661d70fc15b1a55dc97ebfce8Daniel Dunbar if (conf->wpa_pairwise & WPA_CIPHER_CCMP) { 651e465df22f312a3661d70fc15b1a55dc97ebfce8Daniel Dunbar RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); 66b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman pos += WPA_SELECTOR_LEN; 67b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman num_suites++; 68b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman } 69b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman if (conf->wpa_pairwise & WPA_CIPHER_TKIP) { 70b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); 71b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman pos += WPA_SELECTOR_LEN; 7267c8601677a6a4b01a77855b8b51240ef44acfb3Nuno Lopes num_suites++; 7367c8601677a6a4b01a77855b8b51240ef44acfb3Nuno Lopes } 74b529d830b3b1667157da92ab0b5c32e1acfafbabEli Friedman if (conf->wpa_pairwise & WPA_CIPHER_NONE) { 75e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE); 76e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner pos += WPA_SELECTOR_LEN; 77e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner num_suites++; 784ec339f43c0cae2678334850c90926bea10999c7Douglas Gregor } 794ec339f43c0cae2678334850c90926bea10999c7Douglas Gregor 80e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner if (num_suites == 0) { 81e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", 82e2f56196e916e4d2f9eeec5c8978490cdedb3f64Chris Lattner conf->wpa_pairwise); 8391b9f2072a20906dd34ac6cb83813debf3595328Anders Carlsson return -1; 8491b9f2072a20906dd34ac6cb83813debf3595328Anders Carlsson } 85d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor WPA_PUT_LE16(count, num_suites); 86d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor 87d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor num_suites = 0; 88d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor count = pos; 89d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor pos += 2; 90d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor 91d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 92d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X); 93d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor pos += WPA_SELECTOR_LEN; 94d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor num_suites++; 95d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor } 96d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { 97d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X); 98d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor pos += WPA_SELECTOR_LEN; 99d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor num_suites++; 100d079b2d6005bdade40ae4a0f228aba2affc591cfDouglas Gregor } 101d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor 102d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor if (num_suites == 0) { 103d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", 104d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor conf->wpa_key_mgmt); 105d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor return -1; 106d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor } 107d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor WPA_PUT_LE16(count, num_suites); 108d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor 109392cf91c7b3270a9b27baa3c5b21a836f3330d98Sebastian Redl /* WPA Capabilities; use defaults, so no need to include it */ 110d863517ab7e936cbc3244a0fc431c8b672f5ece4Douglas Gregor 111 hdr->len = (pos - buf) - 2; 112 113 return pos - buf; 114} 115 116 117int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, 118 const u8 *pmkid) 119{ 120 struct rsn_ie_hdr *hdr; 121 int num_suites; 122 u8 *pos, *count; 123 u16 capab; 124 125 hdr = (struct rsn_ie_hdr *) buf; 126 hdr->elem_id = WLAN_EID_RSN; 127 WPA_PUT_LE16(hdr->version, RSN_VERSION); 128 pos = (u8 *) (hdr + 1); 129 130 if (conf->wpa_group == WPA_CIPHER_CCMP) { 131 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 132 } else if (conf->wpa_group == WPA_CIPHER_TKIP) { 133 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 134 } else if (conf->wpa_group == WPA_CIPHER_WEP104) { 135 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104); 136 } else if (conf->wpa_group == WPA_CIPHER_WEP40) { 137 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40); 138 } else { 139 wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", 140 conf->wpa_group); 141 return -1; 142 } 143 pos += RSN_SELECTOR_LEN; 144 145 num_suites = 0; 146 count = pos; 147 pos += 2; 148 149#ifdef CONFIG_RSN_TESTING 150 if (rsn_testing) { 151 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); 152 pos += RSN_SELECTOR_LEN; 153 num_suites++; 154 } 155#endif /* CONFIG_RSN_TESTING */ 156 157 if (conf->rsn_pairwise & WPA_CIPHER_CCMP) { 158 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); 159 pos += RSN_SELECTOR_LEN; 160 num_suites++; 161 } 162 if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { 163 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); 164 pos += RSN_SELECTOR_LEN; 165 num_suites++; 166 } 167 if (conf->rsn_pairwise & WPA_CIPHER_NONE) { 168 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE); 169 pos += RSN_SELECTOR_LEN; 170 num_suites++; 171 } 172 173#ifdef CONFIG_RSN_TESTING 174 if (rsn_testing) { 175 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); 176 pos += RSN_SELECTOR_LEN; 177 num_suites++; 178 } 179#endif /* CONFIG_RSN_TESTING */ 180 181 if (num_suites == 0) { 182 wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", 183 conf->rsn_pairwise); 184 return -1; 185 } 186 WPA_PUT_LE16(count, num_suites); 187 188 num_suites = 0; 189 count = pos; 190 pos += 2; 191 192#ifdef CONFIG_RSN_TESTING 193 if (rsn_testing) { 194 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); 195 pos += RSN_SELECTOR_LEN; 196 num_suites++; 197 } 198#endif /* CONFIG_RSN_TESTING */ 199 200 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 201 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X); 202 pos += RSN_SELECTOR_LEN; 203 num_suites++; 204 } 205 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { 206 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X); 207 pos += RSN_SELECTOR_LEN; 208 num_suites++; 209 } 210#ifdef CONFIG_IEEE80211R 211 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 212 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); 213 pos += RSN_SELECTOR_LEN; 214 num_suites++; 215 } 216 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) { 217 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); 218 pos += RSN_SELECTOR_LEN; 219 num_suites++; 220 } 221#endif /* CONFIG_IEEE80211R */ 222#ifdef CONFIG_IEEE80211W 223 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 224 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256); 225 pos += RSN_SELECTOR_LEN; 226 num_suites++; 227 } 228 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 229 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256); 230 pos += RSN_SELECTOR_LEN; 231 num_suites++; 232 } 233#endif /* CONFIG_IEEE80211W */ 234 235#ifdef CONFIG_RSN_TESTING 236 if (rsn_testing) { 237 RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); 238 pos += RSN_SELECTOR_LEN; 239 num_suites++; 240 } 241#endif /* CONFIG_RSN_TESTING */ 242 243 if (num_suites == 0) { 244 wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", 245 conf->wpa_key_mgmt); 246 return -1; 247 } 248 WPA_PUT_LE16(count, num_suites); 249 250 /* RSN Capabilities */ 251 capab = 0; 252 if (conf->rsn_preauth) 253 capab |= WPA_CAPABILITY_PREAUTH; 254 if (conf->peerkey) 255 capab |= WPA_CAPABILITY_PEERKEY_ENABLED; 256 if (conf->wmm_enabled) { 257 /* 4 PTKSA replay counters when using WMM */ 258 capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); 259 } 260#ifdef CONFIG_IEEE80211W 261 if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 262 capab |= WPA_CAPABILITY_MFPC; 263 if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 264 capab |= WPA_CAPABILITY_MFPR; 265 } 266#endif /* CONFIG_IEEE80211W */ 267#ifdef CONFIG_RSN_TESTING 268 if (rsn_testing) 269 capab |= BIT(8) | BIT(14) | BIT(15); 270#endif /* CONFIG_RSN_TESTING */ 271 WPA_PUT_LE16(pos, capab); 272 pos += 2; 273 274 if (pmkid) { 275 if (pos + 2 + PMKID_LEN > buf + len) 276 return -1; 277 /* PMKID Count */ 278 WPA_PUT_LE16(pos, 1); 279 pos += 2; 280 os_memcpy(pos, pmkid, PMKID_LEN); 281 pos += PMKID_LEN; 282 } 283 284#ifdef CONFIG_IEEE80211W 285 if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 286 if (pos + 2 + 4 > buf + len) 287 return -1; 288 if (pmkid == NULL) { 289 /* PMKID Count */ 290 WPA_PUT_LE16(pos, 0); 291 pos += 2; 292 } 293 294 /* Management Group Cipher Suite */ 295 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 296 pos += RSN_SELECTOR_LEN; 297 } 298#endif /* CONFIG_IEEE80211W */ 299 300#ifdef CONFIG_RSN_TESTING 301 if (rsn_testing) { 302 /* 303 * Fill in any defined fields and add extra data to the end of 304 * the element. 305 */ 306 int pmkid_count_set = pmkid != NULL; 307 if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) 308 pmkid_count_set = 1; 309 /* PMKID Count */ 310 WPA_PUT_LE16(pos, 0); 311 pos += 2; 312 if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) { 313 /* Management Group Cipher Suite */ 314 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 315 pos += RSN_SELECTOR_LEN; 316 } 317 318 os_memset(pos, 0x12, 17); 319 pos += 17; 320 } 321#endif /* CONFIG_RSN_TESTING */ 322 323 hdr->len = (pos - buf) - 2; 324 325 return pos - buf; 326} 327 328 329int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) 330{ 331 u8 *pos, buf[128]; 332 int res; 333 334 pos = buf; 335 336 if (wpa_auth->conf.wpa & WPA_PROTO_RSN) { 337 res = wpa_write_rsn_ie(&wpa_auth->conf, 338 pos, buf + sizeof(buf) - pos, NULL); 339 if (res < 0) 340 return res; 341 pos += res; 342 } 343#ifdef CONFIG_IEEE80211R 344 if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) { 345 res = wpa_write_mdie(&wpa_auth->conf, pos, 346 buf + sizeof(buf) - pos); 347 if (res < 0) 348 return res; 349 pos += res; 350 } 351#endif /* CONFIG_IEEE80211R */ 352 if (wpa_auth->conf.wpa & WPA_PROTO_WPA) { 353 res = wpa_write_wpa_ie(&wpa_auth->conf, 354 pos, buf + sizeof(buf) - pos); 355 if (res < 0) 356 return res; 357 pos += res; 358 } 359 360 os_free(wpa_auth->wpa_ie); 361 wpa_auth->wpa_ie = os_malloc(pos - buf); 362 if (wpa_auth->wpa_ie == NULL) 363 return -1; 364 os_memcpy(wpa_auth->wpa_ie, buf, pos - buf); 365 wpa_auth->wpa_ie_len = pos - buf; 366 367 return 0; 368} 369 370 371u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len, 372 const u8 *data2, size_t data2_len) 373{ 374 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 375 *pos++ = RSN_SELECTOR_LEN + data_len + data2_len; 376 RSN_SELECTOR_PUT(pos, kde); 377 pos += RSN_SELECTOR_LEN; 378 os_memcpy(pos, data, data_len); 379 pos += data_len; 380 if (data2) { 381 os_memcpy(pos, data2, data2_len); 382 pos += data2_len; 383 } 384 return pos; 385} 386 387 388struct wpa_auth_okc_iter_data { 389 struct rsn_pmksa_cache_entry *pmksa; 390 const u8 *aa; 391 const u8 *spa; 392 const u8 *pmkid; 393}; 394 395 396static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx) 397{ 398 struct wpa_auth_okc_iter_data *data = ctx; 399 data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa, 400 data->pmkid); 401 if (data->pmksa) 402 return 1; 403 return 0; 404} 405 406 407int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, 408 struct wpa_state_machine *sm, 409 const u8 *wpa_ie, size_t wpa_ie_len, 410 const u8 *mdie, size_t mdie_len) 411{ 412 struct wpa_ie_data data; 413 int ciphers, key_mgmt, res, version; 414 u32 selector; 415 size_t i; 416 const u8 *pmkid = NULL; 417 418 if (wpa_auth == NULL || sm == NULL) 419 return WPA_NOT_ENABLED; 420 421 if (wpa_ie == NULL || wpa_ie_len < 1) 422 return WPA_INVALID_IE; 423 424 if (wpa_ie[0] == WLAN_EID_RSN) 425 version = WPA_PROTO_RSN; 426 else 427 version = WPA_PROTO_WPA; 428 429 if (!(wpa_auth->conf.wpa & version)) { 430 wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR, 431 version, MAC2STR(sm->addr)); 432 return WPA_INVALID_PROTO; 433 } 434 435 if (version == WPA_PROTO_RSN) { 436 res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data); 437 438 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; 439 if (0) { 440 } 441#ifdef CONFIG_IEEE80211R 442 else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) 443 selector = RSN_AUTH_KEY_MGMT_FT_802_1X; 444 else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) 445 selector = RSN_AUTH_KEY_MGMT_FT_PSK; 446#endif /* CONFIG_IEEE80211R */ 447#ifdef CONFIG_IEEE80211W 448 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) 449 selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256; 450 else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) 451 selector = RSN_AUTH_KEY_MGMT_PSK_SHA256; 452#endif /* CONFIG_IEEE80211W */ 453 else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) 454 selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; 455 else if (data.key_mgmt & WPA_KEY_MGMT_PSK) 456 selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X; 457 wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; 458 459 selector = RSN_CIPHER_SUITE_CCMP; 460 if (data.pairwise_cipher & WPA_CIPHER_CCMP) 461 selector = RSN_CIPHER_SUITE_CCMP; 462 else if (data.pairwise_cipher & WPA_CIPHER_TKIP) 463 selector = RSN_CIPHER_SUITE_TKIP; 464 else if (data.pairwise_cipher & WPA_CIPHER_WEP104) 465 selector = RSN_CIPHER_SUITE_WEP104; 466 else if (data.pairwise_cipher & WPA_CIPHER_WEP40) 467 selector = RSN_CIPHER_SUITE_WEP40; 468 else if (data.pairwise_cipher & WPA_CIPHER_NONE) 469 selector = RSN_CIPHER_SUITE_NONE; 470 wpa_auth->dot11RSNAPairwiseCipherSelected = selector; 471 472 selector = RSN_CIPHER_SUITE_CCMP; 473 if (data.group_cipher & WPA_CIPHER_CCMP) 474 selector = RSN_CIPHER_SUITE_CCMP; 475 else if (data.group_cipher & WPA_CIPHER_TKIP) 476 selector = RSN_CIPHER_SUITE_TKIP; 477 else if (data.group_cipher & WPA_CIPHER_WEP104) 478 selector = RSN_CIPHER_SUITE_WEP104; 479 else if (data.group_cipher & WPA_CIPHER_WEP40) 480 selector = RSN_CIPHER_SUITE_WEP40; 481 else if (data.group_cipher & WPA_CIPHER_NONE) 482 selector = RSN_CIPHER_SUITE_NONE; 483 wpa_auth->dot11RSNAGroupCipherSelected = selector; 484 } else { 485 res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data); 486 487 selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; 488 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) 489 selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; 490 else if (data.key_mgmt & WPA_KEY_MGMT_PSK) 491 selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X; 492 wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; 493 494 selector = WPA_CIPHER_SUITE_TKIP; 495 if (data.pairwise_cipher & WPA_CIPHER_CCMP) 496 selector = WPA_CIPHER_SUITE_CCMP; 497 else if (data.pairwise_cipher & WPA_CIPHER_TKIP) 498 selector = WPA_CIPHER_SUITE_TKIP; 499 else if (data.pairwise_cipher & WPA_CIPHER_WEP104) 500 selector = WPA_CIPHER_SUITE_WEP104; 501 else if (data.pairwise_cipher & WPA_CIPHER_WEP40) 502 selector = WPA_CIPHER_SUITE_WEP40; 503 else if (data.pairwise_cipher & WPA_CIPHER_NONE) 504 selector = WPA_CIPHER_SUITE_NONE; 505 wpa_auth->dot11RSNAPairwiseCipherSelected = selector; 506 507 selector = WPA_CIPHER_SUITE_TKIP; 508 if (data.group_cipher & WPA_CIPHER_CCMP) 509 selector = WPA_CIPHER_SUITE_CCMP; 510 else if (data.group_cipher & WPA_CIPHER_TKIP) 511 selector = WPA_CIPHER_SUITE_TKIP; 512 else if (data.group_cipher & WPA_CIPHER_WEP104) 513 selector = WPA_CIPHER_SUITE_WEP104; 514 else if (data.group_cipher & WPA_CIPHER_WEP40) 515 selector = WPA_CIPHER_SUITE_WEP40; 516 else if (data.group_cipher & WPA_CIPHER_NONE) 517 selector = WPA_CIPHER_SUITE_NONE; 518 wpa_auth->dot11RSNAGroupCipherSelected = selector; 519 } 520 if (res) { 521 wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from " 522 MACSTR " (res=%d)", MAC2STR(sm->addr), res); 523 wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len); 524 return WPA_INVALID_IE; 525 } 526 527 if (data.group_cipher != wpa_auth->conf.wpa_group) { 528 wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from " 529 MACSTR, data.group_cipher, MAC2STR(sm->addr)); 530 return WPA_INVALID_GROUP; 531 } 532 533 key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; 534 if (!key_mgmt) { 535 wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " 536 MACSTR, data.key_mgmt, MAC2STR(sm->addr)); 537 return WPA_INVALID_AKMP; 538 } 539 if (0) { 540 } 541#ifdef CONFIG_IEEE80211R 542 else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) 543 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; 544 else if (key_mgmt & WPA_KEY_MGMT_FT_PSK) 545 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK; 546#endif /* CONFIG_IEEE80211R */ 547#ifdef CONFIG_IEEE80211W 548 else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) 549 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256; 550 else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256) 551 sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256; 552#endif /* CONFIG_IEEE80211W */ 553 else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X) 554 sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X; 555 else 556 sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; 557 558 if (version == WPA_PROTO_RSN) 559 ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; 560 else 561 ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; 562 if (!ciphers) { 563 wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) " 564 "from " MACSTR, 565 version == WPA_PROTO_RSN ? "RSN" : "WPA", 566 data.pairwise_cipher, MAC2STR(sm->addr)); 567 return WPA_INVALID_PAIRWISE; 568 } 569 570#ifdef CONFIG_IEEE80211W 571 if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { 572 if (!(data.capabilities & WPA_CAPABILITY_MFPC)) { 573 wpa_printf(MSG_DEBUG, "Management frame protection " 574 "required, but client did not enable it"); 575 return WPA_MGMT_FRAME_PROTECTION_VIOLATION; 576 } 577 578 if (ciphers & WPA_CIPHER_TKIP) { 579 wpa_printf(MSG_DEBUG, "Management frame protection " 580 "cannot use TKIP"); 581 return WPA_MGMT_FRAME_PROTECTION_VIOLATION; 582 } 583 584 if (data.mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) { 585 wpa_printf(MSG_DEBUG, "Unsupported management group " 586 "cipher %d", data.mgmt_group_cipher); 587 return WPA_INVALID_MGMT_GROUP_CIPHER; 588 } 589 } 590 591 if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION || 592 !(data.capabilities & WPA_CAPABILITY_MFPC)) 593 sm->mgmt_frame_prot = 0; 594 else 595 sm->mgmt_frame_prot = 1; 596#endif /* CONFIG_IEEE80211W */ 597 598#ifdef CONFIG_IEEE80211R 599 if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { 600 if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) { 601 wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but " 602 "MDIE not included"); 603 return WPA_INVALID_MDIE; 604 } 605 if (os_memcmp(mdie, wpa_auth->conf.mobility_domain, 606 MOBILITY_DOMAIN_ID_LEN) != 0) { 607 wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown " 608 "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN); 609 return WPA_INVALID_MDIE; 610 } 611 } 612#endif /* CONFIG_IEEE80211R */ 613 614 if (ciphers & WPA_CIPHER_CCMP) 615 sm->pairwise = WPA_CIPHER_CCMP; 616 else 617 sm->pairwise = WPA_CIPHER_TKIP; 618 619 /* TODO: clear WPA/WPA2 state if STA changes from one to another */ 620 if (wpa_ie[0] == WLAN_EID_RSN) 621 sm->wpa = WPA_VERSION_WPA2; 622 else 623 sm->wpa = WPA_VERSION_WPA; 624 625 sm->pmksa = NULL; 626 for (i = 0; i < data.num_pmkid; i++) { 627 wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID", 628 &data.pmkid[i * PMKID_LEN], PMKID_LEN); 629 sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr, 630 &data.pmkid[i * PMKID_LEN]); 631 if (sm->pmksa) { 632 pmkid = sm->pmksa->pmkid; 633 break; 634 } 635 } 636 for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc && 637 i < data.num_pmkid; i++) { 638 struct wpa_auth_okc_iter_data idata; 639 idata.pmksa = NULL; 640 idata.aa = wpa_auth->addr; 641 idata.spa = sm->addr; 642 idata.pmkid = &data.pmkid[i * PMKID_LEN]; 643 wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata); 644 if (idata.pmksa) { 645 wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 646 "OKC match for PMKID"); 647 sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa, 648 idata.pmksa, 649 wpa_auth->addr, 650 idata.pmkid); 651 pmkid = idata.pmkid; 652 break; 653 } 654 } 655 if (sm->pmksa) { 656 wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, 657 "PMKID found from PMKSA cache " 658 "eap_type=%d vlan_id=%d", 659 sm->pmksa->eap_type_authsrv, 660 sm->pmksa->vlan_id); 661 os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN); 662 } 663 664 if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) { 665 os_free(sm->wpa_ie); 666 sm->wpa_ie = os_malloc(wpa_ie_len); 667 if (sm->wpa_ie == NULL) 668 return WPA_ALLOC_FAIL; 669 } 670 os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len); 671 sm->wpa_ie_len = wpa_ie_len; 672 673 return WPA_IE_OK; 674} 675 676 677/** 678 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs 679 * @pos: Pointer to the IE header 680 * @end: Pointer to the end of the Key Data buffer 681 * @ie: Pointer to parsed IE data 682 * Returns: 0 on success, 1 if end mark is found, -1 on failure 683 */ 684static int wpa_parse_generic(const u8 *pos, const u8 *end, 685 struct wpa_eapol_ie_parse *ie) 686{ 687 if (pos[1] == 0) 688 return 1; 689 690 if (pos[1] >= 6 && 691 RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE && 692 pos[2 + WPA_SELECTOR_LEN] == 1 && 693 pos[2 + WPA_SELECTOR_LEN + 1] == 0) { 694 ie->wpa_ie = pos; 695 ie->wpa_ie_len = pos[1] + 2; 696 return 0; 697 } 698 699 if (pos + 1 + RSN_SELECTOR_LEN < end && 700 pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN && 701 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) { 702 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN; 703 return 0; 704 } 705 706 if (pos[1] > RSN_SELECTOR_LEN + 2 && 707 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) { 708 ie->gtk = pos + 2 + RSN_SELECTOR_LEN; 709 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN; 710 return 0; 711 } 712 713 if (pos[1] > RSN_SELECTOR_LEN + 2 && 714 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) { 715 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN; 716 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN; 717 return 0; 718 } 719 720#ifdef CONFIG_PEERKEY 721 if (pos[1] > RSN_SELECTOR_LEN + 2 && 722 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) { 723 ie->smk = pos + 2 + RSN_SELECTOR_LEN; 724 ie->smk_len = pos[1] - RSN_SELECTOR_LEN; 725 return 0; 726 } 727 728 if (pos[1] > RSN_SELECTOR_LEN + 2 && 729 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) { 730 ie->nonce = pos + 2 + RSN_SELECTOR_LEN; 731 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN; 732 return 0; 733 } 734 735 if (pos[1] > RSN_SELECTOR_LEN + 2 && 736 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) { 737 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN; 738 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN; 739 return 0; 740 } 741 742 if (pos[1] > RSN_SELECTOR_LEN + 2 && 743 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) { 744 ie->error = pos + 2 + RSN_SELECTOR_LEN; 745 ie->error_len = pos[1] - RSN_SELECTOR_LEN; 746 return 0; 747 } 748#endif /* CONFIG_PEERKEY */ 749 750#ifdef CONFIG_IEEE80211W 751 if (pos[1] > RSN_SELECTOR_LEN + 2 && 752 RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) { 753 ie->igtk = pos + 2 + RSN_SELECTOR_LEN; 754 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN; 755 return 0; 756 } 757#endif /* CONFIG_IEEE80211W */ 758 759 return 0; 760} 761 762 763/** 764 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs 765 * @buf: Pointer to the Key Data buffer 766 * @len: Key Data Length 767 * @ie: Pointer to parsed IE data 768 * Returns: 0 on success, -1 on failure 769 */ 770int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) 771{ 772 const u8 *pos, *end; 773 int ret = 0; 774 775 os_memset(ie, 0, sizeof(*ie)); 776 for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) { 777 if (pos[0] == 0xdd && 778 ((pos == buf + len - 1) || pos[1] == 0)) { 779 /* Ignore padding */ 780 break; 781 } 782 if (pos + 2 + pos[1] > end) { 783 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data " 784 "underflow (ie=%d len=%d pos=%d)", 785 pos[0], pos[1], (int) (pos - buf)); 786 wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", 787 buf, len); 788 ret = -1; 789 break; 790 } 791 if (*pos == WLAN_EID_RSN) { 792 ie->rsn_ie = pos; 793 ie->rsn_ie_len = pos[1] + 2; 794#ifdef CONFIG_IEEE80211R 795 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) { 796 ie->mdie = pos; 797 ie->mdie_len = pos[1] + 2; 798 } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) { 799 ie->ftie = pos; 800 ie->ftie_len = pos[1] + 2; 801#endif /* CONFIG_IEEE80211R */ 802 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) { 803 ret = wpa_parse_generic(pos, end, ie); 804 if (ret < 0) 805 break; 806 if (ret > 0) { 807 ret = 0; 808 break; 809 } 810 } else { 811 wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key " 812 "Key Data IE", pos, 2 + pos[1]); 813 } 814 } 815 816 return ret; 817} 818 819 820int wpa_auth_uses_mfp(struct wpa_state_machine *sm) 821{ 822 return sm ? sm->mgmt_frame_prot : 0; 823} 824