Branch data Line data Source code
1 : : /*
2 : : * wpa_supplicant - WPA/RSN IE and KDE processing
3 : : * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "includes.h"
10 : :
11 : : #include "common.h"
12 : : #include "wpa.h"
13 : : #include "pmksa_cache.h"
14 : : #include "common/ieee802_11_defs.h"
15 : : #include "wpa_i.h"
16 : : #include "wpa_ie.h"
17 : :
18 : :
19 : : /**
20 : : * wpa_parse_wpa_ie - Parse WPA/RSN IE
21 : : * @wpa_ie: Pointer to WPA or RSN IE
22 : : * @wpa_ie_len: Length of the WPA/RSN IE
23 : : * @data: Pointer to data area for parsing results
24 : : * Returns: 0 on success, -1 on failure
25 : : *
26 : : * Parse the contents of WPA or RSN IE and write the parsed data into data.
27 : : */
28 : 740 : int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
29 : : struct wpa_ie_data *data)
30 : : {
31 [ + - ][ + + ]: 740 : if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
32 : 724 : return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
33 : : else
34 : 740 : return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
35 : : }
36 : :
37 : :
38 : 9 : static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
39 : : int pairwise_cipher, int group_cipher,
40 : : int key_mgmt)
41 : : {
42 : : u8 *pos;
43 : : struct wpa_ie_hdr *hdr;
44 : : u32 suite;
45 : :
46 [ - + ]: 9 : if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN +
47 : : 2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN)
48 : 0 : return -1;
49 : :
50 : 9 : hdr = (struct wpa_ie_hdr *) wpa_ie;
51 : 9 : hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
52 : 9 : RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
53 : 9 : WPA_PUT_LE16(hdr->version, WPA_VERSION);
54 : 9 : pos = (u8 *) (hdr + 1);
55 : :
56 : 9 : suite = wpa_cipher_to_suite(WPA_PROTO_WPA, group_cipher);
57 [ - + ]: 9 : if (suite == 0) {
58 : 0 : wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
59 : : group_cipher);
60 : 0 : return -1;
61 : : }
62 : 9 : RSN_SELECTOR_PUT(pos, suite);
63 : 9 : pos += WPA_SELECTOR_LEN;
64 : :
65 : 9 : *pos++ = 1;
66 : 9 : *pos++ = 0;
67 : 9 : suite = wpa_cipher_to_suite(WPA_PROTO_WPA, pairwise_cipher);
68 [ + - - + ]: 18 : if (suite == 0 ||
69 [ # # ]: 9 : (!wpa_cipher_valid_pairwise(pairwise_cipher) &&
70 : : pairwise_cipher != WPA_CIPHER_NONE)) {
71 : 0 : wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
72 : : pairwise_cipher);
73 : 0 : return -1;
74 : : }
75 : 9 : RSN_SELECTOR_PUT(pos, suite);
76 : 9 : pos += WPA_SELECTOR_LEN;
77 : :
78 : 9 : *pos++ = 1;
79 : 9 : *pos++ = 0;
80 [ + + ]: 9 : if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
81 : 1 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
82 [ + + ]: 8 : } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
83 : 5 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
84 [ + - ]: 3 : } else if (key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
85 : 3 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE);
86 [ # # ]: 0 : } else if (key_mgmt == WPA_KEY_MGMT_CCKM) {
87 : 0 : RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_CCKM);
88 : : } else {
89 : 0 : wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
90 : : key_mgmt);
91 : 0 : return -1;
92 : : }
93 : 9 : pos += WPA_SELECTOR_LEN;
94 : :
95 : : /* WPA Capabilities; use defaults, so no need to include it */
96 : :
97 : 9 : hdr->len = (pos - wpa_ie) - 2;
98 : :
99 : : WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
100 : :
101 : 9 : return pos - wpa_ie;
102 : : }
103 : :
104 : :
105 : 270 : static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
106 : : int pairwise_cipher, int group_cipher,
107 : : int key_mgmt, int mgmt_group_cipher,
108 : : struct wpa_sm *sm)
109 : : {
110 : : u8 *pos;
111 : : struct rsn_ie_hdr *hdr;
112 : : u16 capab;
113 : : u32 suite;
114 : :
115 [ - + ]: 270 : if (rsn_ie_len < sizeof(*hdr) + RSN_SELECTOR_LEN +
116 [ + + ]: 270 : 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN + 2 +
117 : 270 : (sm->cur_pmksa ? 2 + PMKID_LEN : 0)) {
118 : 0 : wpa_printf(MSG_DEBUG, "RSN: Too short IE buffer (%lu bytes)",
119 : : (unsigned long) rsn_ie_len);
120 : 0 : return -1;
121 : : }
122 : :
123 : 270 : hdr = (struct rsn_ie_hdr *) rsn_ie;
124 : 270 : hdr->elem_id = WLAN_EID_RSN;
125 : 270 : WPA_PUT_LE16(hdr->version, RSN_VERSION);
126 : 270 : pos = (u8 *) (hdr + 1);
127 : :
128 : 270 : suite = wpa_cipher_to_suite(WPA_PROTO_RSN, group_cipher);
129 [ - + ]: 270 : if (suite == 0) {
130 : 0 : wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
131 : : group_cipher);
132 : 0 : return -1;
133 : : }
134 : 270 : RSN_SELECTOR_PUT(pos, suite);
135 : 270 : pos += RSN_SELECTOR_LEN;
136 : :
137 : 270 : *pos++ = 1;
138 : 270 : *pos++ = 0;
139 : 270 : suite = wpa_cipher_to_suite(WPA_PROTO_RSN, pairwise_cipher);
140 [ + - - + ]: 540 : if (suite == 0 ||
141 [ # # ]: 270 : (!wpa_cipher_valid_pairwise(pairwise_cipher) &&
142 : : pairwise_cipher != WPA_CIPHER_NONE)) {
143 : 0 : wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
144 : : pairwise_cipher);
145 : 0 : return -1;
146 : : }
147 : 270 : RSN_SELECTOR_PUT(pos, suite);
148 : 270 : pos += RSN_SELECTOR_LEN;
149 : :
150 : 270 : *pos++ = 1;
151 : 270 : *pos++ = 0;
152 [ + + ]: 270 : if (key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
153 : 65 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
154 [ + + ]: 205 : } else if (key_mgmt == WPA_KEY_MGMT_PSK) {
155 : 146 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
156 [ - + ]: 59 : } else if (key_mgmt == WPA_KEY_MGMT_CCKM) {
157 : 0 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_CCKM);
158 : : #ifdef CONFIG_IEEE80211R
159 [ + + ]: 59 : } else if (key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
160 : 3 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
161 [ + + ]: 56 : } else if (key_mgmt == WPA_KEY_MGMT_FT_PSK) {
162 : 11 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
163 : : #endif /* CONFIG_IEEE80211R */
164 : : #ifdef CONFIG_IEEE80211W
165 [ + + ]: 45 : } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SHA256) {
166 : 1 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
167 [ + + ]: 44 : } else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
168 : 6 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
169 : : #endif /* CONFIG_IEEE80211W */
170 : : #ifdef CONFIG_SAE
171 [ + + ]: 38 : } else if (key_mgmt == WPA_KEY_MGMT_SAE) {
172 : 32 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
173 [ + - ]: 6 : } else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
174 : 6 : RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
175 : : #endif /* CONFIG_SAE */
176 : : } else {
177 : 0 : wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
178 : : key_mgmt);
179 : 0 : return -1;
180 : : }
181 : 270 : pos += RSN_SELECTOR_LEN;
182 : :
183 : : /* RSN Capabilities */
184 : 270 : capab = 0;
185 : : #ifdef CONFIG_IEEE80211W
186 [ + + ]: 270 : if (sm->mfp)
187 : 54 : capab |= WPA_CAPABILITY_MFPC;
188 [ + + ]: 270 : if (sm->mfp == 2)
189 : 5 : capab |= WPA_CAPABILITY_MFPR;
190 : : #endif /* CONFIG_IEEE80211W */
191 : 270 : WPA_PUT_LE16(pos, capab);
192 : 270 : pos += 2;
193 : :
194 [ + + ]: 270 : if (sm->cur_pmksa) {
195 : : /* PMKID Count (2 octets, little endian) */
196 : 6 : *pos++ = 1;
197 : 6 : *pos++ = 0;
198 : : /* PMKID */
199 : 6 : os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
200 : 6 : pos += PMKID_LEN;
201 : : }
202 : :
203 : : #ifdef CONFIG_IEEE80211W
204 [ + + ]: 270 : if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
205 [ + - ]: 13 : if (!sm->cur_pmksa) {
206 : : /* PMKID Count */
207 : 13 : WPA_PUT_LE16(pos, 0);
208 : 13 : pos += 2;
209 : : }
210 : :
211 : : /* Management Group Cipher Suite */
212 : 13 : RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
213 : 13 : pos += RSN_SELECTOR_LEN;
214 : : }
215 : : #endif /* CONFIG_IEEE80211W */
216 : :
217 : 270 : hdr->len = (pos - rsn_ie) - 2;
218 : :
219 : : WPA_ASSERT((size_t) (pos - rsn_ie) <= rsn_ie_len);
220 : :
221 : 270 : return pos - rsn_ie;
222 : : }
223 : :
224 : :
225 : : /**
226 : : * wpa_gen_wpa_ie - Generate WPA/RSN IE based on current security policy
227 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
228 : : * @wpa_ie: Pointer to memory area for the generated WPA/RSN IE
229 : : * @wpa_ie_len: Maximum length of the generated WPA/RSN IE
230 : : * Returns: Length of the generated WPA/RSN IE or -1 on failure
231 : : */
232 : 279 : int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
233 : : {
234 [ + + ]: 279 : if (sm->proto == WPA_PROTO_RSN)
235 : 270 : return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
236 : 270 : sm->pairwise_cipher,
237 : 270 : sm->group_cipher,
238 : 540 : sm->key_mgmt, sm->mgmt_group_cipher,
239 : : sm);
240 : : else
241 : 279 : return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
242 : 9 : sm->pairwise_cipher,
243 : 9 : sm->group_cipher,
244 : 9 : sm->key_mgmt);
245 : : }
246 : :
247 : :
248 : : /**
249 : : * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
250 : : * @pos: Pointer to the IE header
251 : : * @end: Pointer to the end of the Key Data buffer
252 : : * @ie: Pointer to parsed IE data
253 : : * Returns: 0 on success, 1 if end mark is found, -1 on failure
254 : : */
255 : 1942 : static int wpa_parse_generic(const u8 *pos, const u8 *end,
256 : : struct wpa_eapol_ie_parse *ie)
257 : : {
258 [ - + ]: 1942 : if (pos[1] == 0)
259 : 0 : return 1;
260 : :
261 [ + + + + ]: 3741 : if (pos[1] >= 6 &&
262 [ + - ]: 1833 : RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
263 [ + - ]: 34 : pos[2 + WPA_SELECTOR_LEN] == 1 &&
264 : 34 : pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
265 : 34 : ie->wpa_ie = pos;
266 : 34 : ie->wpa_ie_len = pos[1] + 2;
267 : 34 : wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
268 : 34 : ie->wpa_ie, ie->wpa_ie_len);
269 : 34 : return 0;
270 : : }
271 : :
272 [ + - ][ + + ]: 1908 : if (pos + 1 + RSN_SELECTOR_LEN < end &&
273 [ + + ]: 1670 : pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
274 : 1670 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
275 : 87 : ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
276 : 87 : wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
277 : 87 : pos, pos[1] + 2);
278 : 87 : return 0;
279 : : }
280 : :
281 [ + + + + ]: 3499 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
282 : 1678 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
283 : 247 : ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
284 : 247 : ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
285 : 247 : wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key",
286 : 247 : pos, pos[1] + 2);
287 : 247 : return 0;
288 : : }
289 : :
290 [ + + + + ]: 3005 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
291 : 1431 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
292 : 3 : ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
293 : 3 : ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
294 : 3 : wpa_hexdump(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key",
295 : 3 : pos, pos[1] + 2);
296 : 3 : return 0;
297 : : }
298 : :
299 : : #ifdef CONFIG_PEERKEY
300 [ + + + + ]: 2999 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
301 : 1428 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
302 : 2 : ie->smk = pos + 2 + RSN_SELECTOR_LEN;
303 : 2 : ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
304 : 2 : wpa_hexdump_key(MSG_DEBUG, "WPA: SMK in EAPOL-Key",
305 : 2 : pos, pos[1] + 2);
306 : 2 : return 0;
307 : : }
308 : :
309 [ + + + + ]: 2995 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
310 : 1426 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
311 : 2 : ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
312 : 2 : ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
313 : 2 : wpa_hexdump(MSG_DEBUG, "WPA: Nonce in EAPOL-Key",
314 : 2 : pos, pos[1] + 2);
315 : 2 : return 0;
316 : : }
317 : :
318 [ + + + + ]: 2991 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
319 : 1424 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
320 : 4 : ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
321 : 4 : ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
322 : 4 : wpa_hexdump(MSG_DEBUG, "WPA: Lifetime in EAPOL-Key",
323 : 4 : pos, pos[1] + 2);
324 : 4 : return 0;
325 : : }
326 : :
327 [ + + - + ]: 2983 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
328 : 1420 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
329 : 0 : ie->error = pos + 2 + RSN_SELECTOR_LEN;
330 : 0 : ie->error_len = pos[1] - RSN_SELECTOR_LEN;
331 : 0 : wpa_hexdump(MSG_DEBUG, "WPA: Error in EAPOL-Key",
332 : 0 : pos, pos[1] + 2);
333 : 0 : return 0;
334 : : }
335 : : #endif /* CONFIG_PEERKEY */
336 : :
337 : : #ifdef CONFIG_IEEE80211W
338 [ + + + + ]: 2983 : if (pos[1] > RSN_SELECTOR_LEN + 2 &&
339 : 1420 : RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
340 : 12 : ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
341 : 12 : ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
342 : 12 : wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
343 : 12 : pos, pos[1] + 2);
344 : 12 : return 0;
345 : : }
346 : : #endif /* CONFIG_IEEE80211W */
347 : :
348 : 1942 : return 0;
349 : : }
350 : :
351 : :
352 : : /**
353 : : * wpa_supplicant_parse_ies - Parse EAPOL-Key Key Data IEs
354 : : * @buf: Pointer to the Key Data buffer
355 : : * @len: Key Data Length
356 : : * @ie: Pointer to parsed IE data
357 : : * Returns: 0 on success, -1 on failure
358 : : */
359 : 1427 : int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
360 : : struct wpa_eapol_ie_parse *ie)
361 : : {
362 : : const u8 *pos, *end;
363 : 1427 : int ret = 0;
364 : :
365 : 1427 : os_memset(ie, 0, sizeof(*ie));
366 [ + + ]: 9215 : for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
367 [ + + ][ + - ]: 8033 : if (pos[0] == 0xdd &&
368 [ + + ]: 2187 : ((pos == buf + len - 1) || pos[1] == 0)) {
369 : : /* Ignore padding */
370 : : break;
371 : : }
372 [ - + ]: 7788 : if (pos + 2 + pos[1] > end) {
373 : 0 : wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
374 : : "underflow (ie=%d len=%d pos=%d)",
375 : 0 : pos[0], pos[1], (int) (pos - buf));
376 : 0 : wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
377 : : buf, len);
378 : 0 : ret = -1;
379 : 0 : break;
380 : : }
381 [ + + ]: 7788 : if (*pos == WLAN_EID_RSN) {
382 : 644 : ie->rsn_ie = pos;
383 : 644 : ie->rsn_ie_len = pos[1] + 2;
384 : 644 : wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
385 : 644 : ie->rsn_ie, ie->rsn_ie_len);
386 [ + + ]: 7144 : } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
387 : 50 : ie->mdie = pos;
388 : 50 : ie->mdie_len = pos[1] + 2;
389 : 50 : wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
390 : 50 : ie->mdie, ie->mdie_len);
391 [ + + ]: 7094 : } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
392 : 104 : ie->ftie = pos;
393 : 104 : ie->ftie_len = pos[1] + 2;
394 : 104 : wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
395 : 104 : ie->ftie, ie->ftie_len);
396 [ + + ][ + - ]: 6990 : } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
397 [ + + ]: 144 : if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
398 : 8 : ie->reassoc_deadline = pos;
399 : 8 : wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
400 : : "in EAPOL-Key",
401 : 16 : ie->reassoc_deadline, pos[1] + 2);
402 [ + - ]: 64 : } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
403 : 64 : ie->key_lifetime = pos;
404 : 64 : wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
405 : : "in EAPOL-Key",
406 : 128 : ie->key_lifetime, pos[1] + 2);
407 : : } else {
408 : 0 : wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
409 : : "EAPOL-Key Key Data IE",
410 : 0 : pos, 2 + pos[1]);
411 : : }
412 [ + + ]: 6918 : } else if (*pos == WLAN_EID_LINK_ID) {
413 [ + - ]: 84 : if (pos[1] >= 18) {
414 : 84 : ie->lnkid = pos;
415 : 84 : ie->lnkid_len = pos[1] + 2;
416 : : }
417 [ + + ]: 6834 : } else if (*pos == WLAN_EID_EXT_CAPAB) {
418 : 856 : ie->ext_capab = pos;
419 : 856 : ie->ext_capab_len = pos[1] + 2;
420 [ + + ]: 5978 : } else if (*pos == WLAN_EID_SUPP_RATES) {
421 : 856 : ie->supp_rates = pos;
422 : 856 : ie->supp_rates_len = pos[1] + 2;
423 [ + + ]: 5122 : } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
424 : 619 : ie->ext_supp_rates = pos;
425 : 619 : ie->ext_supp_rates_len = pos[1] + 2;
426 [ + + ]: 4503 : } else if (*pos == WLAN_EID_HT_CAP) {
427 : 419 : ie->ht_capabilities = pos + 2;
428 : 419 : ie->ht_capabilities_len = pos[1];
429 [ - + ]: 4084 : } else if (*pos == WLAN_EID_VHT_AID) {
430 [ # # ]: 0 : if (pos[1] >= 2)
431 : 0 : ie->aid = WPA_GET_LE16(pos + 2);
432 [ - + ]: 4084 : } else if (*pos == WLAN_EID_VHT_CAP) {
433 : 0 : ie->vht_capabilities = pos + 2;
434 : 0 : ie->vht_capabilities_len = pos[1];
435 [ - + ][ # # ]: 4084 : } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
436 : 0 : ie->qosinfo = pos[2];
437 [ + + ]: 4084 : } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
438 : 1942 : ret = wpa_parse_generic(pos, end, ie);
439 [ - + ]: 1942 : if (ret < 0)
440 : 0 : break;
441 [ - + ]: 1942 : if (ret > 0) {
442 : 0 : ret = 0;
443 : 0 : break;
444 : : }
445 : : } else {
446 : 2142 : wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
447 : 2142 : "Key Data IE", pos, 2 + pos[1]);
448 : : }
449 : : }
450 : :
451 : 1427 : return ret;
452 : : }
|