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