]> git.ipfire.org Git - thirdparty/hostap.git/blob - wlantest/rx_eapol.c
Make struct wpa_eapol_key easier to use with variable length MIC
[thirdparty/hostap.git] / wlantest / rx_eapol.c
1 /*
2 * Received Data frame processing for EAPOL messages
3 * Copyright (c) 2010-2015, 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 "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "crypto/aes_wrap.h"
13 #include "crypto/crypto.h"
14 #include "common/defs.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/ieee802_11_common.h"
17 #include "common/eapol_common.h"
18 #include "common/wpa_common.h"
19 #include "rsn_supp/wpa_ie.h"
20 #include "wlantest.h"
21
22
23 static int is_zero(const u8 *buf, size_t len)
24 {
25 size_t i;
26 for (i = 0; i < len; i++) {
27 if (buf[i])
28 return 0;
29 }
30 return 1;
31 }
32
33
34 static int check_mic(const u8 *kck, size_t kck_len, int akmp, int ver,
35 const u8 *data, size_t len)
36 {
37 u8 *buf;
38 int ret = -1;
39 struct ieee802_1x_hdr *hdr;
40 struct wpa_eapol_key *key;
41 u8 rx_mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
42 size_t mic_len = wpa_mic_len(akmp);
43
44 buf = os_malloc(len);
45 if (buf == NULL)
46 return -1;
47 os_memcpy(buf, data, len);
48 hdr = (struct ieee802_1x_hdr *) buf;
49 key = (struct wpa_eapol_key *) (hdr + 1);
50
51 os_memcpy(rx_mic, key + 1, mic_len);
52 os_memset(key + 1, 0, mic_len);
53
54 if (wpa_eapol_key_mic(kck, kck_len, akmp, ver, buf, len,
55 (u8 *) (key + 1)) == 0 &&
56 os_memcmp(rx_mic, key + 1, mic_len) == 0)
57 ret = 0;
58
59 os_free(buf);
60
61 return ret;
62 }
63
64
65 static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
66 const u8 *src, const u8 *data, size_t len)
67 {
68 struct wlantest_bss *bss;
69 struct wlantest_sta *sta;
70 const struct ieee802_1x_hdr *eapol;
71 const struct wpa_eapol_key *hdr;
72
73 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
74 MAC2STR(src), MAC2STR(dst));
75 bss = bss_get(wt, src);
76 if (bss == NULL)
77 return;
78 sta = sta_get(bss, dst);
79 if (sta == NULL)
80 return;
81
82 eapol = (const struct ieee802_1x_hdr *) data;
83 hdr = (const struct wpa_eapol_key *) (eapol + 1);
84 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
85 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
86 " used zero nonce", MAC2STR(src));
87 }
88 if (!is_zero(hdr->key_rsc, 8)) {
89 add_note(wt, MSG_INFO, "EAPOL-Key 1/4 from " MACSTR
90 " used non-zero Key RSC", MAC2STR(src));
91 }
92 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
93 }
94
95
96 static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
97 struct wlantest_sta *sta, u16 ver,
98 const u8 *data, size_t len,
99 struct wlantest_pmk *pmk)
100 {
101 struct wpa_ptk ptk;
102
103 if (wpa_key_mgmt_ft(sta->key_mgmt)) {
104 u8 pmk_r0[PMK_LEN];
105 u8 pmk_r0_name[WPA_PMK_NAME_LEN];
106 u8 pmk_r1[PMK_LEN];
107 u8 pmk_r1_name[WPA_PMK_NAME_LEN];
108 u8 ptk_name[WPA_PMK_NAME_LEN];
109
110 wpa_derive_pmk_r0(pmk->pmk, sizeof(pmk->pmk),
111 bss->ssid, bss->ssid_len, bss->mdid,
112 bss->r0kh_id, bss->r0kh_id_len,
113 sta->addr, pmk_r0, pmk_r0_name);
114 wpa_hexdump(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
115 wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name,
116 WPA_PMK_NAME_LEN);
117 wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, bss->r1kh_id,
118 sta->addr, pmk_r1, pmk_r1_name);
119 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
120 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name,
121 WPA_PMK_NAME_LEN);
122 if (wpa_pmk_r1_to_ptk(pmk_r1, sta->snonce, sta->anonce,
123 sta->addr,
124 bss->bssid, pmk_r1_name, &ptk, ptk_name,
125 sta->key_mgmt,
126 sta->pairwise_cipher) < 0 ||
127 check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
128 len) < 0)
129 return -1;
130 } else if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
131 "Pairwise key expansion",
132 bss->bssid, sta->addr, sta->anonce,
133 sta->snonce, &ptk, sta->key_mgmt,
134 sta->pairwise_cipher) < 0 ||
135 check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
136 len) < 0) {
137 return -1;
138 }
139
140 sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
141 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
142 MAC2STR(sta->addr), MAC2STR(bss->bssid));
143 sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
144 if (sta->ptk_set) {
145 /*
146 * Rekeying - use new PTK for EAPOL-Key frames, but continue
147 * using the old PTK for frame decryption.
148 */
149 add_note(wt, MSG_DEBUG, "Derived PTK during rekeying");
150 os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
151 wpa_hexdump(MSG_DEBUG, "TPTK:KCK",
152 sta->tptk.kck, sta->tptk.kck_len);
153 wpa_hexdump(MSG_DEBUG, "TPTK:KEK",
154 sta->tptk.kek, sta->tptk.kek_len);
155 wpa_hexdump(MSG_DEBUG, "TPTK:TK",
156 sta->tptk.tk, sta->tptk.tk_len);
157 sta->tptk_set = 1;
158 return 0;
159 }
160 add_note(wt, MSG_DEBUG, "Derived new PTK");
161 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
162 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, sta->ptk.kck_len);
163 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, sta->ptk.kek_len);
164 wpa_hexdump(MSG_DEBUG, "PTK:TK", sta->ptk.tk, sta->ptk.tk_len);
165 sta->ptk_set = 1;
166 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
167 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
168 return 0;
169 }
170
171
172 static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
173 struct wlantest_sta *sta, u16 ver,
174 const u8 *data, size_t len)
175 {
176 struct wlantest_pmk *pmk;
177
178 wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR " (ver %u)",
179 MAC2STR(sta->addr), ver);
180 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
181 wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
182 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
183 return;
184 }
185
186 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
187 wpa_printf(MSG_DEBUG, "Try global PMK");
188 if (try_pmk(wt, bss, sta, ver, data, len, pmk) == 0)
189 return;
190 }
191
192 if (!sta->ptk_set) {
193 struct wlantest_ptk *ptk;
194 int prev_level = wpa_debug_level;
195
196 wpa_debug_level = MSG_WARNING;
197 dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
198 if (check_mic(ptk->ptk.kck, ptk->ptk.kck_len,
199 sta->key_mgmt, ver, data, len) < 0)
200 continue;
201 wpa_printf(MSG_INFO, "Pre-set PTK matches for STA "
202 MACSTR " BSSID " MACSTR,
203 MAC2STR(sta->addr), MAC2STR(bss->bssid));
204 add_note(wt, MSG_DEBUG, "Using pre-set PTK");
205 ptk->ptk_len = 32 +
206 wpa_cipher_key_len(sta->pairwise_cipher);
207 os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
208 wpa_hexdump(MSG_DEBUG, "PTK:KCK",
209 sta->ptk.kck, sta->ptk.kck_len);
210 wpa_hexdump(MSG_DEBUG, "PTK:KEK",
211 sta->ptk.kek, sta->ptk.kek_len);
212 wpa_hexdump(MSG_DEBUG, "PTK:TK",
213 sta->ptk.tk, sta->ptk.tk_len);
214 sta->ptk_set = 1;
215 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
216 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
217 }
218 wpa_debug_level = prev_level;
219 }
220
221 add_note(wt, MSG_DEBUG, "No matching PMK found to derive PTK");
222 }
223
224
225 static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
226 const u8 *src, const u8 *data, size_t len)
227 {
228 struct wlantest_bss *bss;
229 struct wlantest_sta *sta;
230 const struct ieee802_1x_hdr *eapol;
231 const struct wpa_eapol_key *hdr;
232 const u8 *key_data, *kck, *mic;
233 size_t kck_len, mic_len;
234 u16 key_info, key_data_len;
235 struct wpa_eapol_ie_parse ie;
236
237 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
238 MAC2STR(src), MAC2STR(dst));
239 bss = bss_get(wt, dst);
240 if (bss == NULL)
241 return;
242 sta = sta_get(bss, src);
243 if (sta == NULL)
244 return;
245
246 eapol = (const struct ieee802_1x_hdr *) data;
247 hdr = (const struct wpa_eapol_key *) (eapol + 1);
248 mic_len = wpa_mic_len(sta->key_mgmt);
249 mic = (const u8 *) (hdr + 1);
250 if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
251 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
252 " used zero nonce", MAC2STR(src));
253 }
254 if (!is_zero(hdr->key_rsc, 8)) {
255 add_note(wt, MSG_INFO, "EAPOL-Key 2/4 from " MACSTR
256 " used non-zero Key RSC", MAC2STR(src));
257 }
258 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
259 key_info = WPA_GET_BE16(hdr->key_info);
260 key_data_len = WPA_GET_BE16(mic + mic_len);
261 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
262
263 if (!sta->ptk_set && !sta->tptk_set) {
264 add_note(wt, MSG_DEBUG,
265 "No PTK known to process EAPOL-Key 2/4");
266 return;
267 }
268
269 kck = sta->ptk.kck;
270 kck_len = sta->ptk.kck_len;
271 if (sta->tptk_set) {
272 add_note(wt, MSG_DEBUG,
273 "Use TPTK for validation EAPOL-Key MIC");
274 kck = sta->tptk.kck;
275 kck_len = sta->tptk.kck_len;
276 }
277 if (check_mic(kck, kck_len, sta->key_mgmt,
278 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
279 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
280 return;
281 }
282 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
283
284 key_data = mic + mic_len + 2;
285
286 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
287 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
288 return;
289 }
290
291 if (ie.wpa_ie) {
292 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
293 ie.wpa_ie, ie.wpa_ie_len);
294 if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
295 struct ieee802_11_elems elems;
296 add_note(wt, MSG_INFO,
297 "Mismatch in WPA IE between EAPOL-Key 2/4 "
298 "and (Re)Association Request from " MACSTR,
299 MAC2STR(sta->addr));
300 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
301 ie.wpa_ie, ie.wpa_ie_len);
302 wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
303 "Request",
304 sta->rsnie,
305 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
306 /*
307 * The sniffer may have missed (Re)Association
308 * Request, so try to survive with the information from
309 * EAPOL-Key.
310 */
311 os_memset(&elems, 0, sizeof(elems));
312 elems.wpa_ie = ie.wpa_ie + 2;
313 elems.wpa_ie_len = ie.wpa_ie_len - 2;
314 wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
315 "IE in EAPOL-Key 2/4");
316 sta_update_assoc(sta, &elems);
317 }
318 }
319
320 if (ie.rsn_ie) {
321 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
322 ie.rsn_ie, ie.rsn_ie_len);
323 if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
324 struct ieee802_11_elems elems;
325 add_note(wt, MSG_INFO,
326 "Mismatch in RSN IE between EAPOL-Key 2/4 "
327 "and (Re)Association Request from " MACSTR,
328 MAC2STR(sta->addr));
329 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
330 ie.rsn_ie, ie.rsn_ie_len);
331 wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
332 "Request",
333 sta->rsnie,
334 sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
335 /*
336 * The sniffer may have missed (Re)Association
337 * Request, so try to survive with the information from
338 * EAPOL-Key.
339 */
340 os_memset(&elems, 0, sizeof(elems));
341 elems.rsn_ie = ie.rsn_ie + 2;
342 elems.rsn_ie_len = ie.rsn_ie_len - 2;
343 wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
344 "IE in EAPOL-Key 2/4");
345 sta_update_assoc(sta, &elems);
346 }
347 }
348 }
349
350
351 static u8 * decrypt_eapol_key_data_rc4(struct wlantest *wt, const u8 *kek,
352 const struct wpa_eapol_key *hdr,
353 const u8 *keydata, u16 keydatalen,
354 size_t *len)
355 {
356 u8 ek[32], *buf;
357
358 buf = os_malloc(keydatalen);
359 if (buf == NULL)
360 return NULL;
361
362 os_memcpy(ek, hdr->key_iv, 16);
363 os_memcpy(ek + 16, kek, 16);
364 os_memcpy(buf, keydata, keydatalen);
365 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
366 add_note(wt, MSG_INFO, "RC4 failed");
367 os_free(buf);
368 return NULL;
369 }
370
371 *len = keydatalen;
372 return buf;
373 }
374
375
376 static u8 * decrypt_eapol_key_data_aes(struct wlantest *wt, const u8 *kek,
377 const struct wpa_eapol_key *hdr,
378 const u8 *keydata, u16 keydatalen,
379 size_t *len)
380 {
381 u8 *buf;
382
383 if (keydatalen % 8) {
384 add_note(wt, MSG_INFO, "Unsupported AES-WRAP len %d",
385 keydatalen);
386 return NULL;
387 }
388 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
389 buf = os_malloc(keydatalen);
390 if (buf == NULL)
391 return NULL;
392 if (aes_unwrap(kek, 16, keydatalen / 8, keydata, buf)) {
393 os_free(buf);
394 add_note(wt, MSG_INFO,
395 "AES unwrap failed - could not decrypt EAPOL-Key "
396 "key data");
397 return NULL;
398 }
399
400 *len = keydatalen;
401 return buf;
402 }
403
404
405 static u8 * decrypt_eapol_key_data(struct wlantest *wt, int akmp, const u8 *kek,
406 size_t kek_len, u16 ver,
407 const struct wpa_eapol_key *hdr,
408 size_t *len)
409 {
410 size_t mic_len;
411 u16 keydatalen;
412 const u8 *mic, *keydata;
413
414 if (kek_len != 16)
415 return NULL;
416
417 mic = (const u8 *) (hdr + 1);
418 mic_len = wpa_mic_len(akmp);
419 keydata = mic + mic_len + 2;
420 keydatalen = WPA_GET_BE16(mic + mic_len);
421
422 switch (ver) {
423 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
424 return decrypt_eapol_key_data_rc4(wt, kek, hdr, keydata,
425 keydatalen, len);
426 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
427 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
428 return decrypt_eapol_key_data_aes(wt, kek, hdr, keydata,
429 keydatalen, len);
430 case WPA_KEY_INFO_TYPE_AKM_DEFINED:
431 /* For now, assume this is OSEN */
432 return decrypt_eapol_key_data_aes(wt, kek, hdr, keydata,
433 keydatalen, len);
434 default:
435 add_note(wt, MSG_INFO,
436 "Unsupported EAPOL-Key Key Descriptor Version %u",
437 ver);
438 return NULL;
439 }
440 }
441
442
443 static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
444 struct wlantest_sta *sta,
445 const u8 *buf, size_t len, const u8 *rsc)
446 {
447 struct wpa_eapol_ie_parse ie;
448
449 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
450 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
451 return;
452 }
453
454 if (ie.wpa_ie) {
455 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
456 ie.wpa_ie, ie.wpa_ie_len);
457 }
458
459 if (ie.rsn_ie) {
460 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
461 ie.rsn_ie, ie.rsn_ie_len);
462 }
463
464 if (ie.gtk) {
465 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
466 ie.gtk, ie.gtk_len);
467 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
468 int id;
469 id = ie.gtk[0] & 0x03;
470 add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
471 id, !!(ie.gtk[0] & 0x04));
472 if ((ie.gtk[0] & 0xf8) || ie.gtk[1]) {
473 add_note(wt, MSG_INFO,
474 "GTK KDE: Reserved field set: "
475 "%02x %02x", ie.gtk[0], ie.gtk[1]);
476 }
477 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
478 ie.gtk_len - 2);
479 bss->gtk_len[id] = ie.gtk_len - 2;
480 sta->gtk_len = ie.gtk_len - 2;
481 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
482 os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
483 bss->rsc[id][0] = rsc[5];
484 bss->rsc[id][1] = rsc[4];
485 bss->rsc[id][2] = rsc[3];
486 bss->rsc[id][3] = rsc[2];
487 bss->rsc[id][4] = rsc[1];
488 bss->rsc[id][5] = rsc[0];
489 bss->gtk_idx = id;
490 sta->gtk_idx = id;
491 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
492 } else {
493 add_note(wt, MSG_INFO, "Invalid GTK KDE length %u",
494 (unsigned) ie.gtk_len);
495 }
496 }
497
498 if (ie.igtk) {
499 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
500 ie.igtk, ie.igtk_len);
501 if (ie.igtk_len == 24) {
502 u16 id;
503 id = WPA_GET_LE16(ie.igtk);
504 if (id > 5) {
505 add_note(wt, MSG_INFO,
506 "Unexpected IGTK KeyID %u", id);
507 } else {
508 const u8 *ipn;
509 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
510 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
511 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
512 16);
513 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
514 bss->igtk_len[id] = 16;
515 ipn = ie.igtk + 2;
516 bss->ipn[id][0] = ipn[5];
517 bss->ipn[id][1] = ipn[4];
518 bss->ipn[id][2] = ipn[3];
519 bss->ipn[id][3] = ipn[2];
520 bss->ipn[id][4] = ipn[1];
521 bss->ipn[id][5] = ipn[0];
522 bss->igtk_idx = id;
523 }
524 } else if (ie.igtk_len == 40) {
525 u16 id;
526 id = WPA_GET_LE16(ie.igtk);
527 if (id > 5) {
528 add_note(wt, MSG_INFO,
529 "Unexpected IGTK KeyID %u", id);
530 } else {
531 const u8 *ipn;
532 add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
533 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
534 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
535 32);
536 os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
537 bss->igtk_len[id] = 32;
538 ipn = ie.igtk + 2;
539 bss->ipn[id][0] = ipn[5];
540 bss->ipn[id][1] = ipn[4];
541 bss->ipn[id][2] = ipn[3];
542 bss->ipn[id][3] = ipn[2];
543 bss->ipn[id][4] = ipn[1];
544 bss->ipn[id][5] = ipn[0];
545 bss->igtk_idx = id;
546 }
547 } else {
548 add_note(wt, MSG_INFO, "Invalid IGTK KDE length %u",
549 (unsigned) ie.igtk_len);
550 }
551 }
552 }
553
554
555 static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
556 const u8 *src, const u8 *data, size_t len)
557 {
558 struct wlantest_bss *bss;
559 struct wlantest_sta *sta;
560 const struct ieee802_1x_hdr *eapol;
561 const struct wpa_eapol_key *hdr;
562 const u8 *key_data, *kck, *kek, *mic;
563 size_t kck_len, kek_len, mic_len;
564 int recalc = 0;
565 u16 key_info, ver;
566 u8 *decrypted_buf = NULL;
567 const u8 *decrypted;
568 size_t decrypted_len = 0;
569 struct wpa_eapol_ie_parse ie;
570
571 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
572 MAC2STR(src), MAC2STR(dst));
573 bss = bss_get(wt, src);
574 if (bss == NULL)
575 return;
576 sta = sta_get(bss, dst);
577 if (sta == NULL)
578 return;
579 mic_len = wpa_mic_len(sta->key_mgmt);
580
581 eapol = (const struct ieee802_1x_hdr *) data;
582 hdr = (const struct wpa_eapol_key *) (eapol + 1);
583 mic = (const u8 *) (hdr + 1);
584 key_info = WPA_GET_BE16(hdr->key_info);
585
586 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
587 add_note(wt, MSG_INFO,
588 "EAPOL-Key ANonce mismatch between 1/4 and 3/4");
589 recalc = 1;
590 }
591 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
592 if (recalc) {
593 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
594 data, len);
595 }
596
597 if (!sta->ptk_set && !sta->tptk_set) {
598 add_note(wt, MSG_DEBUG,
599 "No PTK known to process EAPOL-Key 3/4");
600 return;
601 }
602
603 kek = sta->ptk.kek;
604 kek_len = sta->ptk.kek_len;
605 kck = sta->ptk.kck;
606 kck_len = sta->ptk.kck_len;
607 if (sta->tptk_set) {
608 add_note(wt, MSG_DEBUG,
609 "Use TPTK for validation EAPOL-Key MIC");
610 kck = sta->tptk.kck;
611 kck_len = sta->tptk.kck_len;
612 kek = sta->tptk.kek;
613 kek_len = sta->tptk.kek_len;
614 }
615 if (check_mic(kck, kck_len, sta->key_mgmt,
616 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
617 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
618 return;
619 }
620 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
621
622 key_data = mic + mic_len + 2;
623 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
624 if (sta->proto & WPA_PROTO_RSN)
625 add_note(wt, MSG_INFO,
626 "EAPOL-Key 3/4 without EncrKeyData bit");
627 decrypted = key_data;
628 decrypted_len = WPA_GET_BE16(mic + mic_len);
629 } else {
630 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
631 decrypted_buf = decrypt_eapol_key_data(wt, sta->key_mgmt,
632 kek, kek_len, ver,
633 hdr, &decrypted_len);
634 if (decrypted_buf == NULL) {
635 add_note(wt, MSG_INFO,
636 "Failed to decrypt EAPOL-Key Key Data");
637 return;
638 }
639 decrypted = decrypted_buf;
640 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
641 decrypted, decrypted_len);
642 }
643 if (wt->write_pcap_dumper && decrypted != key_data) {
644 /* Fill in a dummy Data frame header */
645 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
646 struct ieee80211_hdr *h;
647 struct wpa_eapol_key *k;
648 const u8 *p;
649 u8 *pos;
650 size_t plain_len;
651
652 plain_len = decrypted_len;
653 p = decrypted;
654 while (p + 1 < decrypted + decrypted_len) {
655 if (p[0] == 0xdd && p[1] == 0x00) {
656 /* Remove padding */
657 plain_len = p - decrypted;
658 break;
659 }
660 p += 2 + p[1];
661 }
662
663 os_memset(buf, 0, sizeof(buf));
664 h = (struct ieee80211_hdr *) buf;
665 h->frame_control = host_to_le16(0x0208);
666 os_memcpy(h->addr1, dst, ETH_ALEN);
667 os_memcpy(h->addr2, src, ETH_ALEN);
668 os_memcpy(h->addr3, src, ETH_ALEN);
669 pos = (u8 *) (h + 1);
670 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
671 pos += 8;
672 os_memcpy(pos, eapol, sizeof(*eapol));
673 pos += sizeof(*eapol);
674 os_memcpy(pos, hdr, sizeof(*hdr) + mic_len);
675 k = (struct wpa_eapol_key *) pos;
676 pos += sizeof(struct wpa_eapol_key) + mic_len;
677 WPA_PUT_BE16(k->key_info,
678 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
679 WPA_PUT_BE16(pos, plain_len);
680 write_pcap_decrypted(wt, buf, sizeof(buf),
681 decrypted, plain_len);
682 }
683
684 if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
685 add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
686 os_free(decrypted_buf);
687 return;
688 }
689
690 if ((ie.wpa_ie &&
691 os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
692 (ie.wpa_ie == NULL && bss->wpaie[0])) {
693 add_note(wt, MSG_INFO,
694 "Mismatch in WPA IE between EAPOL-Key 3/4 and "
695 "Beacon/Probe Response from " MACSTR,
696 MAC2STR(bss->bssid));
697 wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
698 ie.wpa_ie, ie.wpa_ie_len);
699 wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
700 "Response",
701 bss->wpaie,
702 bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
703 }
704
705 if ((ie.rsn_ie &&
706 os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
707 (ie.rsn_ie == NULL && bss->rsnie[0])) {
708 add_note(wt, MSG_INFO, "Mismatch in RSN IE between EAPOL-Key "
709 "3/4 and Beacon/Probe Response from " MACSTR,
710 MAC2STR(bss->bssid));
711 wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
712 ie.rsn_ie, ie.rsn_ie_len);
713 wpa_hexdump(MSG_INFO, "RSN IE in Beacon/Probe Response",
714 bss->rsnie,
715 bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
716 }
717
718 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len, hdr->key_rsc);
719 os_free(decrypted_buf);
720 }
721
722
723 static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
724 const u8 *src, const u8 *data, size_t len)
725 {
726 struct wlantest_bss *bss;
727 struct wlantest_sta *sta;
728 const struct ieee802_1x_hdr *eapol;
729 const struct wpa_eapol_key *hdr;
730 u16 key_info;
731 const u8 *kck;
732 size_t kck_len;
733
734 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
735 MAC2STR(src), MAC2STR(dst));
736 bss = bss_get(wt, dst);
737 if (bss == NULL)
738 return;
739 sta = sta_get(bss, src);
740 if (sta == NULL)
741 return;
742
743 eapol = (const struct ieee802_1x_hdr *) data;
744 hdr = (const struct wpa_eapol_key *) (eapol + 1);
745 if (!is_zero(hdr->key_rsc, 8)) {
746 add_note(wt, MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
747 "non-zero Key RSC", MAC2STR(src));
748 }
749 key_info = WPA_GET_BE16(hdr->key_info);
750
751 if (!sta->ptk_set && !sta->tptk_set) {
752 add_note(wt, MSG_DEBUG,
753 "No PTK known to process EAPOL-Key 4/4");
754 return;
755 }
756
757 kck = sta->ptk.kck;
758 kck_len = sta->ptk.kck_len;
759 if (sta->tptk_set) {
760 add_note(wt, MSG_DEBUG,
761 "Use TPTK for validation EAPOL-Key MIC");
762 kck = sta->tptk.kck;
763 kck_len = sta->tptk.kck_len;
764 }
765 if (check_mic(kck, kck_len, sta->key_mgmt,
766 key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
767 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
768 return;
769 }
770 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
771 if (sta->tptk_set) {
772 add_note(wt, MSG_DEBUG, "Update PTK (rekeying)");
773 os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
774 sta->ptk_set = 1;
775 sta->tptk_set = 0;
776 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
777 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
778 }
779 }
780
781
782 static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
783 const u8 *src, const u8 *data, size_t len)
784 {
785 struct wlantest_bss *bss;
786 struct wlantest_sta *sta;
787 const struct ieee802_1x_hdr *eapol;
788 const struct wpa_eapol_key *hdr;
789 u16 key_info, ver;
790 u8 *decrypted;
791 size_t decrypted_len = 0;
792 size_t mic_len;
793
794 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
795 MAC2STR(src), MAC2STR(dst));
796 bss = bss_get(wt, src);
797 if (bss == NULL)
798 return;
799 sta = sta_get(bss, dst);
800 if (sta == NULL)
801 return;
802 mic_len = wpa_mic_len(sta->key_mgmt);
803
804 eapol = (const struct ieee802_1x_hdr *) data;
805 hdr = (const struct wpa_eapol_key *) (eapol + 1);
806 key_info = WPA_GET_BE16(hdr->key_info);
807
808 if (!sta->ptk_set) {
809 add_note(wt, MSG_DEBUG,
810 "No PTK known to process EAPOL-Key 1/2");
811 return;
812 }
813
814 if (sta->ptk_set &&
815 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
816 key_info & WPA_KEY_INFO_TYPE_MASK,
817 data, len) < 0) {
818 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
819 return;
820 }
821 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
822
823 if (sta->proto & WPA_PROTO_RSN &&
824 !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
825 add_note(wt, MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
826 return;
827 }
828 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
829 decrypted = decrypt_eapol_key_data(wt, sta->key_mgmt,
830 sta->ptk.kek, sta->ptk.kek_len,
831 ver, hdr, &decrypted_len);
832 if (decrypted == NULL) {
833 add_note(wt, MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
834 return;
835 }
836 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
837 decrypted, decrypted_len);
838 if (wt->write_pcap_dumper) {
839 /* Fill in a dummy Data frame header */
840 u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
841 struct ieee80211_hdr *h;
842 struct wpa_eapol_key *k;
843 u8 *pos;
844 size_t plain_len;
845
846 plain_len = decrypted_len;
847 pos = decrypted;
848 while (pos + 1 < decrypted + decrypted_len) {
849 if (pos[0] == 0xdd && pos[1] == 0x00) {
850 /* Remove padding */
851 plain_len = pos - decrypted;
852 break;
853 }
854 pos += 2 + pos[1];
855 }
856
857 os_memset(buf, 0, sizeof(buf));
858 h = (struct ieee80211_hdr *) buf;
859 h->frame_control = host_to_le16(0x0208);
860 os_memcpy(h->addr1, dst, ETH_ALEN);
861 os_memcpy(h->addr2, src, ETH_ALEN);
862 os_memcpy(h->addr3, src, ETH_ALEN);
863 pos = (u8 *) (h + 1);
864 os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
865 pos += 8;
866 os_memcpy(pos, eapol, sizeof(*eapol));
867 pos += sizeof(*eapol);
868 os_memcpy(pos, hdr, sizeof(*hdr) + mic_len);
869 k = (struct wpa_eapol_key *) pos;
870 pos += sizeof(struct wpa_eapol_key) + mic_len;
871 WPA_PUT_BE16(k->key_info,
872 key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
873 WPA_PUT_BE16(pos, plain_len);
874 write_pcap_decrypted(wt, buf, sizeof(buf),
875 decrypted, plain_len);
876 }
877 if (sta->proto & WPA_PROTO_RSN)
878 learn_kde_keys(wt, bss, sta, decrypted, decrypted_len,
879 hdr->key_rsc);
880 else {
881 int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
882 if (decrypted_len == klen) {
883 const u8 *rsc = hdr->key_rsc;
884 int id;
885 id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
886 WPA_KEY_INFO_KEY_INDEX_SHIFT;
887 add_note(wt, MSG_DEBUG, "GTK key index %d", id);
888 wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
889 decrypted_len);
890 bss->gtk_len[id] = decrypted_len;
891 os_memcpy(bss->gtk[id], decrypted, decrypted_len);
892 bss->rsc[id][0] = rsc[5];
893 bss->rsc[id][1] = rsc[4];
894 bss->rsc[id][2] = rsc[3];
895 bss->rsc[id][3] = rsc[2];
896 bss->rsc[id][4] = rsc[1];
897 bss->rsc[id][5] = rsc[0];
898 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
899 } else {
900 add_note(wt, MSG_INFO, "Unexpected WPA Key Data length "
901 "in Group Key msg 1/2 from " MACSTR,
902 MAC2STR(src));
903 }
904 }
905 os_free(decrypted);
906 }
907
908
909 static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
910 const u8 *src, const u8 *data, size_t len)
911 {
912 struct wlantest_bss *bss;
913 struct wlantest_sta *sta;
914 const struct ieee802_1x_hdr *eapol;
915 const struct wpa_eapol_key *hdr;
916 u16 key_info;
917
918 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
919 MAC2STR(src), MAC2STR(dst));
920 bss = bss_get(wt, dst);
921 if (bss == NULL)
922 return;
923 sta = sta_get(bss, src);
924 if (sta == NULL)
925 return;
926
927 eapol = (const struct ieee802_1x_hdr *) data;
928 hdr = (const struct wpa_eapol_key *) (eapol + 1);
929 if (!is_zero(hdr->key_rsc, 8)) {
930 add_note(wt, MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
931 "non-zero Key RSC", MAC2STR(src));
932 }
933 key_info = WPA_GET_BE16(hdr->key_info);
934
935 if (!sta->ptk_set) {
936 add_note(wt, MSG_DEBUG,
937 "No PTK known to process EAPOL-Key 2/2");
938 return;
939 }
940
941 if (sta->ptk_set &&
942 check_mic(sta->ptk.kck, sta->ptk.kck_len, sta->key_mgmt,
943 key_info & WPA_KEY_INFO_TYPE_MASK,
944 data, len) < 0) {
945 add_note(wt, MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
946 return;
947 }
948 add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
949 }
950
951
952 static void rx_data_eapol_key(struct wlantest *wt, const u8 *bssid,
953 const u8 *sta_addr, const u8 *dst,
954 const u8 *src, const u8 *data, size_t len,
955 int prot)
956 {
957 const struct ieee802_1x_hdr *eapol;
958 const struct wpa_eapol_key *hdr;
959 const u8 *key_data;
960 u16 key_info, key_length, ver, key_data_length;
961 size_t mic_len = 16;
962 const u8 *mic;
963 struct wlantest_bss *bss;
964 struct wlantest_sta *sta;
965
966 bss = bss_get(wt, bssid);
967 if (bss) {
968 sta = sta_get(bss, sta_addr);
969 if (sta)
970 mic_len = wpa_mic_len(sta->key_mgmt);
971 }
972
973 eapol = (const struct ieee802_1x_hdr *) data;
974 hdr = (const struct wpa_eapol_key *) (eapol + 1);
975
976 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
977 (const u8 *) hdr, len - sizeof(*eapol));
978 if (len < sizeof(*hdr) + mic_len + 2) {
979 add_note(wt, MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
980 MAC2STR(src));
981 return;
982 }
983 mic = (const u8 *) (hdr + 1);
984
985 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
986 /* TODO: EAPOL-Key RC4 for WEP */
987 wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
988 MACSTR, MAC2STR(src));
989 return;
990 }
991
992 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
993 hdr->type != EAPOL_KEY_TYPE_WPA) {
994 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
995 "%u from " MACSTR, hdr->type, MAC2STR(src));
996 return;
997 }
998
999 key_info = WPA_GET_BE16(hdr->key_info);
1000 key_length = WPA_GET_BE16(hdr->key_length);
1001 key_data_length = WPA_GET_BE16(mic + mic_len);
1002 key_data = mic + mic_len + 2;
1003 if (key_data + key_data_length > data + len) {
1004 add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
1005 MAC2STR(src));
1006 return;
1007 }
1008 if (key_data + key_data_length < data + len) {
1009 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
1010 "field", key_data + key_data_length,
1011 data + len - key_data - key_data_length);
1012 }
1013
1014
1015 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1016 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
1017 "datalen=%u",
1018 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
1019 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1020 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1021 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
1022 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
1023 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
1024 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
1025 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
1026 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
1027 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
1028 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
1029 key_data_length);
1030
1031 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1032 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
1033 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1034 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
1035 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
1036 "Version %u from " MACSTR, ver, MAC2STR(src));
1037 return;
1038 }
1039
1040 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
1041 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
1042 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
1043 hdr->key_nonce, WPA_NONCE_LEN);
1044 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
1045 hdr->key_iv, 16);
1046 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
1047 hdr->key_rsc, WPA_KEY_RSC_LEN);
1048 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
1049 mic, mic_len);
1050 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
1051 key_data, key_data_length);
1052
1053 if (hdr->type == EAPOL_KEY_TYPE_RSN &&
1054 (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
1055 0) {
1056 wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
1057 "Key Info bits 0x%x from " MACSTR,
1058 key_info, MAC2STR(src));
1059 }
1060
1061 if (hdr->type == EAPOL_KEY_TYPE_WPA &&
1062 (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
1063 WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
1064 wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
1065 "Key Info bits 0x%x from " MACSTR,
1066 key_info, MAC2STR(src));
1067 }
1068
1069 if (key_length > 32) {
1070 wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
1071 "from " MACSTR, key_length, MAC2STR(src));
1072 }
1073
1074 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1075 !is_zero(hdr->key_iv, 16)) {
1076 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
1077 "(reserved with ver=%d) field from " MACSTR,
1078 ver, MAC2STR(src));
1079 wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
1080 hdr->key_iv, 16);
1081 }
1082
1083 if (!is_zero(hdr->key_id, 8)) {
1084 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
1085 "(reserved) field from " MACSTR, MAC2STR(src));
1086 wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
1087 hdr->key_id, 8);
1088 }
1089
1090 if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
1091 wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
1092 "(last two are unused)" MACSTR, MAC2STR(src));
1093 }
1094
1095 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
1096 return;
1097
1098 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
1099 return;
1100
1101 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1102 /* 4-Way Handshake */
1103 switch (key_info & (WPA_KEY_INFO_SECURE |
1104 WPA_KEY_INFO_MIC |
1105 WPA_KEY_INFO_ACK |
1106 WPA_KEY_INFO_INSTALL)) {
1107 case WPA_KEY_INFO_ACK:
1108 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
1109 break;
1110 case WPA_KEY_INFO_MIC:
1111 if (key_data_length == 0)
1112 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1113 len);
1114 else
1115 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1116 len);
1117 break;
1118 case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
1119 WPA_KEY_INFO_INSTALL:
1120 /* WPA does not include Secure bit in 3/4 */
1121 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1122 break;
1123 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1124 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
1125 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
1126 break;
1127 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1128 if (key_data_length == 0)
1129 rx_data_eapol_key_4_of_4(wt, dst, src, data,
1130 len);
1131 else
1132 rx_data_eapol_key_2_of_4(wt, dst, src, data,
1133 len);
1134 break;
1135 default:
1136 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1137 break;
1138 }
1139 } else {
1140 /* Group Key Handshake */
1141 switch (key_info & (WPA_KEY_INFO_SECURE |
1142 WPA_KEY_INFO_MIC |
1143 WPA_KEY_INFO_ACK)) {
1144 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
1145 WPA_KEY_INFO_ACK:
1146 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
1147 break;
1148 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
1149 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
1150 break;
1151 default:
1152 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
1153 break;
1154 }
1155 }
1156 }
1157
1158
1159 void rx_data_eapol(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
1160 const u8 *dst, const u8 *src,
1161 const u8 *data, size_t len, int prot)
1162 {
1163 const struct ieee802_1x_hdr *hdr;
1164 u16 length;
1165 const u8 *p;
1166
1167 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
1168 if (len < sizeof(*hdr)) {
1169 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
1170 MAC2STR(src));
1171 return;
1172 }
1173
1174 hdr = (const struct ieee802_1x_hdr *) data;
1175 length = be_to_host16(hdr->length);
1176 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
1177 "type=%u len=%u",
1178 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
1179 hdr->version, hdr->type, length);
1180 if (hdr->version < 1 || hdr->version > 3) {
1181 wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
1182 MACSTR, hdr->version, MAC2STR(src));
1183 }
1184 if (sizeof(*hdr) + length > len) {
1185 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
1186 MAC2STR(src));
1187 return;
1188 }
1189
1190 if (sizeof(*hdr) + length < len) {
1191 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
1192 (int) (len - sizeof(*hdr) - length));
1193 }
1194 p = (const u8 *) (hdr + 1);
1195
1196 switch (hdr->type) {
1197 case IEEE802_1X_TYPE_EAP_PACKET:
1198 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
1199 break;
1200 case IEEE802_1X_TYPE_EAPOL_START:
1201 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
1202 break;
1203 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
1204 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
1205 break;
1206 case IEEE802_1X_TYPE_EAPOL_KEY:
1207 rx_data_eapol_key(wt, bssid, sta_addr, dst, src, data,
1208 sizeof(*hdr) + length, prot);
1209 break;
1210 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
1211 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
1212 p, length);
1213 break;
1214 default:
1215 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
1216 break;
1217 }
1218 }