]> git.ipfire.org Git - thirdparty/hostap.git/blame - wlantest/rx_data.c
wlantest: Add Group Key handshake processing
[thirdparty/hostap.git] / wlantest / rx_data.c
CommitLineData
2d73f0a8
JM
1/*
2 * Received Data frame processing
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "utils/includes.h"
16
17#include "utils/common.h"
8672562b
JM
18#include "crypto/aes_wrap.h"
19#include "crypto/crypto.h"
2d73f0a8 20#include "common/ieee802_11_defs.h"
32234bba
JM
21#include "common/eapol_common.h"
22#include "common/wpa_common.h"
4d9f9ee7 23#include "rsn_supp/wpa_ie.h"
2d73f0a8
JM
24#include "wlantest.h"
25
26
27static const char * data_stype(u16 stype)
28{
29 switch (stype) {
30 case WLAN_FC_STYPE_DATA:
31 return "DATA";
32 case WLAN_FC_STYPE_DATA_CFACK:
33 return "DATA-CFACK";
34 case WLAN_FC_STYPE_DATA_CFPOLL:
35 return "DATA-CFPOLL";
36 case WLAN_FC_STYPE_DATA_CFACKPOLL:
37 return "DATA-CFACKPOLL";
38 case WLAN_FC_STYPE_NULLFUNC:
39 return "NULLFUNC";
40 case WLAN_FC_STYPE_CFACK:
41 return "CFACK";
42 case WLAN_FC_STYPE_CFPOLL:
43 return "CFPOLL";
44 case WLAN_FC_STYPE_CFACKPOLL:
45 return "CFACKPOLL";
46 case WLAN_FC_STYPE_QOS_DATA:
47 return "QOSDATA";
48 case WLAN_FC_STYPE_QOS_DATA_CFACK:
49 return "QOSDATA-CFACK";
50 case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
51 return "QOSDATA-CFPOLL";
52 case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
53 return "QOSDATA-CFACKPOLL";
54 case WLAN_FC_STYPE_QOS_NULL:
55 return "QOS-NULL";
56 case WLAN_FC_STYPE_QOS_CFPOLL:
57 return "QOS-CFPOLL";
58 case WLAN_FC_STYPE_QOS_CFACKPOLL:
59 return "QOS-CFACKPOLL";
60 }
61 return "??";
62}
63
64
53650bca
JM
65static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
66{
67 u8 *buf;
68 int ret = -1;
69 struct ieee802_1x_hdr *hdr;
70 struct wpa_eapol_key *key;
71 u8 rx_mic[16];
72
73 buf = os_malloc(len);
74 if (buf == NULL)
75 return -1;
76 os_memcpy(buf, data, len);
77 hdr = (struct ieee802_1x_hdr *) buf;
78 key = (struct wpa_eapol_key *) (hdr + 1);
79
80 os_memcpy(rx_mic, key->key_mic, 16);
81 os_memset(key->key_mic, 0, 16);
82
83 if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
84 os_memcmp(rx_mic, key->key_mic, 16) == 0)
85 ret = 0;
86
87 os_free(buf);
88
89 return ret;
90}
91
92
32234bba
JM
93static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
94 const u8 *src, const u8 *data, size_t len)
95{
53650bca
JM
96 struct wlantest_bss *bss;
97 struct wlantest_sta *sta;
98 const struct ieee802_1x_hdr *eapol;
99 const struct wpa_eapol_key *hdr;
100
32234bba
JM
101 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
102 MAC2STR(src), MAC2STR(dst));
53650bca
JM
103 bss = bss_get(wt, src);
104 if (bss == NULL)
105 return;
106 sta = sta_get(bss, dst);
107 if (sta == NULL)
108 return;
109
110 eapol = (const struct ieee802_1x_hdr *) data;
111 hdr = (const struct wpa_eapol_key *) (eapol + 1);
112 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
113}
114
115
d06df64d
JM
116static int try_pmk(struct wlantest_bss *bss, struct wlantest_sta *sta,
117 u16 ver, const u8 *data, size_t len,
118 struct wlantest_pmk *pmk)
119{
120 struct wpa_ptk ptk;
121 size_t ptk_len = 48; /* FIX: 64 for TKIP */
122 wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
123 "Pairwise key expansion",
124 bss->bssid, sta->addr, sta->anonce, sta->snonce,
125 (u8 *) &ptk, ptk_len,
126 0 /* FIX: SHA256 based on AKM */);
c09caa58 127 if (check_mic(ptk.kck, ver, data, len) < 0)
d06df64d
JM
128 return -1;
129
c09caa58
JM
130 wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
131 MAC2STR(sta->addr), MAC2STR(bss->bssid));
d06df64d 132 os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
c09caa58
JM
133 wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
134 wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
135 wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
136 if (ptk_len > 48)
137 wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16);
d06df64d 138 sta->ptk_set = 1;
2edd5c23
JM
139 os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
140 os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
d06df64d
JM
141 return 0;
142}
143
144
145static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
146 struct wlantest_sta *sta, u16 ver,
147 const u8 *data, size_t len)
53650bca
JM
148{
149 struct wlantest_pmk *pmk;
150
151 dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
d06df64d
JM
152 if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
153 return;
154 }
155
156 dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
157 if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
158 return;
53650bca 159 }
32234bba
JM
160}
161
162
163static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
164 const u8 *src, const u8 *data, size_t len)
165{
53650bca
JM
166 struct wlantest_bss *bss;
167 struct wlantest_sta *sta;
168 const struct ieee802_1x_hdr *eapol;
169 const struct wpa_eapol_key *hdr;
f0a78297
JM
170 const u8 *key_data;
171 u16 key_info, key_data_len;
172 struct wpa_eapol_ie_parse ie;
53650bca 173
32234bba
JM
174 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
175 MAC2STR(src), MAC2STR(dst));
53650bca
JM
176 bss = bss_get(wt, dst);
177 if (bss == NULL)
178 return;
179 sta = sta_get(bss, src);
180 if (sta == NULL)
181 return;
182
183 eapol = (const struct ieee802_1x_hdr *) data;
184 hdr = (const struct wpa_eapol_key *) (eapol + 1);
185 os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
186 key_info = WPA_GET_BE16(hdr->key_info);
f0a78297 187 key_data_len = WPA_GET_BE16(hdr->key_data_length);
d06df64d 188 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
f0a78297
JM
189
190 if (!sta->ptk_set) {
191 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/4");
192 return;
193 }
194
195 if (check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
196 data, len) < 0) {
197 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
198 return;
199 }
200 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
201
202 key_data = (const u8 *) (hdr + 1);
203
204 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
205 wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
206 return;
207 }
208
209 if (ie.wpa_ie) {
210 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
211 ie.wpa_ie, ie.wpa_ie_len);
212 }
213
214 if (ie.rsn_ie) {
215 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
216 ie.rsn_ie, ie.rsn_ie_len);
217 }
32234bba
JM
218}
219
220
8672562b
JM
221static u8 * decrypt_eapol_key_data_rc4(const u8 *kek,
222 const struct wpa_eapol_key *hdr,
223 size_t *len)
224{
225 u8 ek[32], *buf;
226 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
227
228 buf = os_malloc(keydatalen);
229 if (buf == NULL)
230 return NULL;
231
232 os_memcpy(ek, hdr->key_iv, 16);
233 os_memcpy(ek + 16, kek, 16);
234 os_memcpy(buf, hdr + 1, keydatalen);
235 if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
236 wpa_printf(MSG_INFO, "RC4 failed");
237 os_free(buf);
238 return NULL;
239 }
240
241 *len = keydatalen;
242 return buf;
243}
244
245
246static u8 * decrypt_eapol_key_data_aes(const u8 *kek,
247 const struct wpa_eapol_key *hdr,
248 size_t *len)
249{
250 u8 *buf;
251 u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
252
253 if (keydatalen % 8) {
254 wpa_printf(MSG_INFO, "Unsupported AES-WRAP len %d",
255 keydatalen);
256 return NULL;
257 }
258 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
259 buf = os_malloc(keydatalen);
260 if (buf == NULL)
261 return NULL;
262 if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
263 os_free(buf);
264 wpa_printf(MSG_INFO, "AES unwrap failed - "
265 "could not decrypt EAPOL-Key key data");
266 return NULL;
267 }
268
269 *len = keydatalen;
270 return buf;
271}
272
273
274static u8 * decrypt_eapol_key_data(const u8 *kek, u16 ver,
275 const struct wpa_eapol_key *hdr,
276 size_t *len)
277{
278 switch (ver) {
279 case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
280 return decrypt_eapol_key_data_rc4(kek, hdr, len);
281 case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
282 case WPA_KEY_INFO_TYPE_AES_128_CMAC:
283 return decrypt_eapol_key_data_aes(kek, hdr, len);
284 default:
285 wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
286 "Version %u", ver);
287 return NULL;
288 }
289}
290
291
2edd5c23
JM
292static void learn_kde_keys(struct wlantest_bss *bss, u8 *buf, size_t len,
293 const u8 *rsc)
4d9f9ee7
JM
294{
295 struct wpa_eapol_ie_parse ie;
296
297 if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
298 wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
299 return;
300 }
301
302 if (ie.wpa_ie) {
303 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
304 ie.wpa_ie, ie.wpa_ie_len);
305 }
306
307 if (ie.rsn_ie) {
308 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
309 ie.rsn_ie, ie.rsn_ie_len);
310 }
311
312 if (ie.gtk) {
313 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
314 ie.gtk, ie.gtk_len);
315 if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
316 int id;
317 id = ie.gtk[0] & 0x03;
c09caa58 318 wpa_printf(MSG_DEBUG, "GTK KeyID=%u tx=%u",
4d9f9ee7
JM
319 id, !!(ie.gtk[0] & 0x04));
320 if ((ie.gtk[0] & 0xf8) || ie.gtk[1])
321 wpa_printf(MSG_INFO, "GTK KDE: Reserved field "
322 "set: %02x %02x",
323 ie.gtk[0], ie.gtk[1]);
324 wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
325 ie.gtk_len - 2);
326 bss->gtk_len[id] = ie.gtk_len - 2;
327 os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
2edd5c23
JM
328 bss->rsc[id][0] = rsc[5];
329 bss->rsc[id][1] = rsc[4];
330 bss->rsc[id][2] = rsc[3];
331 bss->rsc[id][3] = rsc[2];
332 bss->rsc[id][4] = rsc[1];
333 bss->rsc[id][5] = rsc[0];
334 wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
4d9f9ee7
JM
335 } else {
336 wpa_printf(MSG_INFO, "Invalid GTK KDE length %u",
337 (unsigned) ie.gtk_len);
338 }
339 }
340
341 if (ie.igtk) {
342 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
343 ie.igtk, ie.igtk_len);
344 if (ie.igtk_len == 24) {
345 u16 id;
346 id = WPA_GET_LE16(ie.igtk);
347 if (id > 5) {
348 wpa_printf(MSG_INFO, "Unexpected IGTK KeyID "
349 "%u", id);
350 } else {
c09caa58
JM
351 wpa_printf(MSG_DEBUG, "IGTK KeyID %u", id);
352 wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
353 wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
354 16);
4d9f9ee7
JM
355 os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
356 bss->igtk_set[id] = 1;
357 }
358 } else {
359 wpa_printf(MSG_INFO, "Invalid IGTK KDE length %u",
360 (unsigned) ie.igtk_len);
361 }
362 }
363}
364
365
32234bba
JM
366static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
367 const u8 *src, const u8 *data, size_t len)
368{
53650bca
JM
369 struct wlantest_bss *bss;
370 struct wlantest_sta *sta;
371 const struct ieee802_1x_hdr *eapol;
372 const struct wpa_eapol_key *hdr;
8672562b 373 const u8 *key_data;
53650bca 374 int recalc = 0;
5db8cf31 375 u16 key_info, ver;
8672562b
JM
376 u8 *decrypted;
377 size_t decrypted_len = 0;
53650bca 378
32234bba
JM
379 wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
380 MAC2STR(src), MAC2STR(dst));
53650bca
JM
381 bss = bss_get(wt, src);
382 if (bss == NULL)
383 return;
384 sta = sta_get(bss, dst);
385 if (sta == NULL)
386 return;
387
388 eapol = (const struct ieee802_1x_hdr *) data;
389 hdr = (const struct wpa_eapol_key *) (eapol + 1);
390 key_info = WPA_GET_BE16(hdr->key_info);
8672562b 391
53650bca
JM
392 if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
393 wpa_printf(MSG_INFO, "EAPOL-Key ANonce mismatch between 1/4 "
394 "and 3/4");
395 recalc = 1;
396 }
397 os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
398 if (recalc) {
d06df64d 399 derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
53650bca
JM
400 data, len);
401 }
402
403 if (!sta->ptk_set) {
404 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 3/4");
405 return;
406 }
407
408 if (check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
409 data, len) < 0) {
410 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
411 return;
412 }
413 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
414
8672562b
JM
415 key_data = (const u8 *) (hdr + 1);
416 /* TODO: handle WPA without EncrKeyData bit */
417 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
418 wpa_printf(MSG_INFO, "EAPOL-Key 3/4 without EncrKeyData bit");
419 return;
420 }
421 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
422 decrypted = decrypt_eapol_key_data(sta->ptk.kek, ver, hdr,
423 &decrypted_len);
424 if (decrypted == NULL) {
425 wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
426 return;
427 }
428 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
429 decrypted, decrypted_len);
2edd5c23 430 learn_kde_keys(bss, decrypted, decrypted_len, hdr->key_rsc);
8672562b 431 os_free(decrypted);
32234bba
JM
432}
433
434
435static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
436 const u8 *src, const u8 *data, size_t len)
437{
53650bca
JM
438 struct wlantest_bss *bss;
439 struct wlantest_sta *sta;
440 const struct ieee802_1x_hdr *eapol;
441 const struct wpa_eapol_key *hdr;
442 u16 key_info;
443
32234bba
JM
444 wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
445 MAC2STR(src), MAC2STR(dst));
53650bca
JM
446 bss = bss_get(wt, dst);
447 if (bss == NULL)
448 return;
449 sta = sta_get(bss, src);
450 if (sta == NULL)
451 return;
452
453 eapol = (const struct ieee802_1x_hdr *) data;
454 hdr = (const struct wpa_eapol_key *) (eapol + 1);
455 key_info = WPA_GET_BE16(hdr->key_info);
456
457 if (!sta->ptk_set) {
458 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 4/4");
459 return;
460 }
461
462 if (sta->ptk_set &&
463 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
464 data, len) < 0) {
465 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
466 return;
467 }
468 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
32234bba
JM
469}
470
471
472static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
473 const u8 *src, const u8 *data, size_t len)
474{
5db8cf31
JM
475 struct wlantest_bss *bss;
476 struct wlantest_sta *sta;
477 const struct ieee802_1x_hdr *eapol;
478 const struct wpa_eapol_key *hdr;
479 const u8 *key_data;
480 u16 key_info, ver;
481 u8 *decrypted;
482 size_t decrypted_len = 0;
483
32234bba
JM
484 wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
485 MAC2STR(src), MAC2STR(dst));
5db8cf31
JM
486 bss = bss_get(wt, src);
487 if (bss == NULL)
488 return;
489 sta = sta_get(bss, dst);
490 if (sta == NULL)
491 return;
492
493 eapol = (const struct ieee802_1x_hdr *) data;
494 hdr = (const struct wpa_eapol_key *) (eapol + 1);
495 key_info = WPA_GET_BE16(hdr->key_info);
496
497 if (!sta->ptk_set) {
498 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 1/2");
499 return;
500 }
501
502 if (sta->ptk_set &&
503 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
504 data, len) < 0) {
505 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
506 return;
507 }
508 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
509
510 key_data = (const u8 *) (hdr + 1);
511 /* TODO: handle WPA without EncrKeyData bit */
512 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
513 wpa_printf(MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
514 return;
515 }
516 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
517 decrypted = decrypt_eapol_key_data(sta->ptk.kek, ver, hdr,
518 &decrypted_len);
519 if (decrypted == NULL) {
520 wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
521 return;
522 }
523 wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
524 decrypted, decrypted_len);
525 learn_kde_keys(bss, decrypted, decrypted_len, hdr->key_rsc);
526 os_free(decrypted);
32234bba
JM
527}
528
529
530static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
531 const u8 *src, const u8 *data, size_t len)
532{
5db8cf31
JM
533 struct wlantest_bss *bss;
534 struct wlantest_sta *sta;
535 const struct ieee802_1x_hdr *eapol;
536 const struct wpa_eapol_key *hdr;
537 u16 key_info;
538
32234bba
JM
539 wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
540 MAC2STR(src), MAC2STR(dst));
5db8cf31
JM
541 bss = bss_get(wt, dst);
542 if (bss == NULL)
543 return;
544 sta = sta_get(bss, src);
545 if (sta == NULL)
546 return;
547
548 eapol = (const struct ieee802_1x_hdr *) data;
549 hdr = (const struct wpa_eapol_key *) (eapol + 1);
550 key_info = WPA_GET_BE16(hdr->key_info);
551
552 if (!sta->ptk_set) {
553 wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/2");
554 return;
555 }
556
557 if (sta->ptk_set &&
558 check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
559 data, len) < 0) {
560 wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
561 return;
562 }
563 wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
32234bba
JM
564}
565
566
567static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
568 const u8 *src, const u8 *data, size_t len,
569 int prot)
570{
53650bca 571 const struct ieee802_1x_hdr *eapol;
32234bba 572 const struct wpa_eapol_key *hdr;
8672562b 573 const u8 *key_data;
32234bba
JM
574 u16 key_info, key_length, ver, key_data_length;
575
53650bca
JM
576 eapol = (const struct ieee802_1x_hdr *) data;
577 hdr = (const struct wpa_eapol_key *) (eapol + 1);
578
579 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
580 (const u8 *) hdr, len - sizeof(*eapol));
32234bba
JM
581 if (len < sizeof(*hdr)) {
582 wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
583 MAC2STR(src));
584 return;
585 }
32234bba
JM
586
587 if (hdr->type == EAPOL_KEY_TYPE_RC4) {
588 /* TODO: EAPOL-Key RC4 for WEP */
589 return;
590 }
591
592 if (hdr->type != EAPOL_KEY_TYPE_RSN &&
593 hdr->type != EAPOL_KEY_TYPE_WPA) {
594 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key type %u",
595 hdr->type);
596 return;
597 }
598
599 key_info = WPA_GET_BE16(hdr->key_info);
600 key_length = WPA_GET_BE16(hdr->key_length);
601 key_data_length = WPA_GET_BE16(hdr->key_data_length);
8672562b
JM
602 key_data = (const u8 *) (hdr + 1);
603 if (key_data + key_data_length > data + len) {
604 wpa_printf(MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
605 MAC2STR(src));
606 return;
607 }
608 if (key_data + key_data_length < data + len) {
609 wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
610 "field", key_data + key_data_length,
611 data + len - key_data - key_data_length);
612 }
613
614
32234bba
JM
615 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
616 wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
617 "datalen=%u",
618 ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
619 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
620 WPA_KEY_INFO_KEY_INDEX_SHIFT,
621 (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
622 (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
623 (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
624 (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
625 (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
626 (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
627 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
628 (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
629 key_data_length);
630
631 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
632 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
633 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
634 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key Key Descriptor "
635 "Version %u", ver);
636 return;
637 }
638
639 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
640 hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
641 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
642 hdr->key_nonce, WPA_NONCE_LEN);
643 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
644 hdr->key_iv, 16);
645 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
2edd5c23 646 hdr->key_rsc, WPA_KEY_RSC_LEN);
32234bba
JM
647 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
648 hdr->key_mic, 16);
8672562b
JM
649 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
650 key_data, key_data_length);
32234bba
JM
651
652 if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
653 return;
654
655 if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
656 return;
657
658 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
659 /* 4-Way Handshake */
660 switch (key_info & (WPA_KEY_INFO_SECURE |
661 WPA_KEY_INFO_MIC |
662 WPA_KEY_INFO_ACK |
663 WPA_KEY_INFO_INSTALL)) {
664 case WPA_KEY_INFO_ACK:
665 rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
666 break;
667 case WPA_KEY_INFO_MIC:
668 rx_data_eapol_key_2_of_4(wt, dst, src, data, len);
669 break;
670 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
671 WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
672 rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
673 break;
674 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
675 rx_data_eapol_key_4_of_4(wt, dst, src, data, len);
676 break;
677 default:
678 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
679 break;
680 }
681 } else {
682 /* Group Key Handshake */
683 switch (key_info & (WPA_KEY_INFO_SECURE |
684 WPA_KEY_INFO_MIC |
685 WPA_KEY_INFO_ACK)) {
686 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
687 WPA_KEY_INFO_ACK:
688 rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
689 break;
690 case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
691 rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
692 break;
693 default:
694 wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
695 break;
696 }
697 }
698}
699
700
701static void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
702 const u8 *data, size_t len, int prot)
703{
704 const struct ieee802_1x_hdr *hdr;
705 u16 length;
706 const u8 *p;
707
708 wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
709 if (len < sizeof(*hdr)) {
710 wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
711 MAC2STR(src));
712 return;
713 }
714
715 hdr = (const struct ieee802_1x_hdr *) data;
716 length = be_to_host16(hdr->length);
717 wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
718 "type=%u len=%u",
719 MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
720 hdr->version, hdr->type, length);
721 if (sizeof(*hdr) + length > len) {
722 wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
723 MAC2STR(src));
724 return;
725 }
726
727 if (sizeof(*hdr) + length < len) {
728 wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
729 (int) (len - sizeof(*hdr) - length));
730 }
731 p = (const u8 *) (hdr + 1);
732
733 switch (hdr->type) {
734 case IEEE802_1X_TYPE_EAP_PACKET:
735 wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
736 break;
737 case IEEE802_1X_TYPE_EAPOL_START:
738 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
739 break;
740 case IEEE802_1X_TYPE_EAPOL_LOGOFF:
741 wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
742 break;
743 case IEEE802_1X_TYPE_EAPOL_KEY:
53650bca
JM
744 rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
745 prot);
32234bba
JM
746 break;
747 case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
748 wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
749 p, length);
750 break;
751 default:
752 wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
753 break;
754 }
755}
756
757
758static void rx_data_eth(struct wlantest *wt, const u8 *dst, const u8 *src,
759 u16 ethertype, const u8 *data, size_t len, int prot)
760{
761 if (ethertype == ETH_P_PAE)
762 rx_data_eapol(wt, dst, src, data, len, prot);
763}
764
765
766static void rx_data_process(struct wlantest *wt, const u8 *dst, const u8 *src,
767 const u8 *data, size_t len, int prot)
768{
4bc82fc7
JM
769 if (len == 0)
770 return;
771
32234bba
JM
772 if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
773 rx_data_eth(wt, dst, src, WPA_GET_BE16(data + 6),
774 data + 8, len - 8, prot);
775 return;
776 }
777
4bc82fc7 778 wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
32234bba
JM
779}
780
781
d318c534
JM
782static void rx_data_bss_prot_group(struct wlantest *wt,
783 const struct ieee80211_hdr *hdr,
784 const u8 *qos, const u8 *dst, const u8 *src,
785 const u8 *data, size_t len)
786{
787 struct wlantest_bss *bss;
788 int keyid;
07d0a5be
JM
789 u8 *decrypted;
790 size_t dlen;
2edd5c23 791 u8 pn[6];
d318c534
JM
792
793 bss = bss_get(wt, hdr->addr2);
794 if (bss == NULL)
795 return;
796 if (len < 4) {
797 wpa_printf(MSG_INFO, "Too short group addressed data frame");
798 return;
799 }
800
801 keyid = data[3] >> 6;
802 if (bss->gtk_len[keyid] == 0) {
803 wpa_printf(MSG_MSGDUMP, "No GTK known to decrypt the frame "
804 "(A2=" MACSTR " KeyID=%d)",
805 MAC2STR(hdr->addr2), keyid);
806 return;
807 }
808
2edd5c23
JM
809 ccmp_get_pn(pn, data);
810 if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
811 wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: SA=" MACSTR,
812 MAC2STR(hdr->addr2));
813 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
814 wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
815 }
816
07d0a5be
JM
817 /* TODO: TKIP */
818
819 decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len, &dlen);
2edd5c23 820 if (decrypted) {
07d0a5be 821 rx_data_process(wt, dst, src, decrypted, dlen, 1);
2edd5c23
JM
822 os_memcpy(bss->rsc[keyid], pn, 6);
823 }
07d0a5be 824 os_free(decrypted);
d318c534
JM
825}
826
827
32234bba
JM
828static void rx_data_bss_prot(struct wlantest *wt,
829 const struct ieee80211_hdr *hdr, const u8 *qos,
830 const u8 *dst, const u8 *src, const u8 *data,
831 size_t len)
832{
d318c534
JM
833 struct wlantest_bss *bss;
834 struct wlantest_sta *sta;
835 int keyid;
836 u16 fc = le_to_host16(hdr->frame_control);
837 u8 *decrypted;
838 size_t dlen;
2edd5c23
JM
839 int tid;
840 u8 pn[6], *rsc;
d318c534
JM
841
842 if (hdr->addr1[0] & 0x01) {
843 rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
844 return;
845 }
846
847 if (fc & WLAN_FC_TODS) {
848 bss = bss_get(wt, hdr->addr1);
849 if (bss == NULL)
850 return;
851 sta = sta_get(bss, hdr->addr2);
852 } else {
853 bss = bss_get(wt, hdr->addr2);
854 if (bss == NULL)
855 return;
856 sta = sta_get(bss, hdr->addr1);
857 }
858 if (sta == NULL || !sta->ptk_set) {
859 wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
860 return;
861 }
862
863 if (len < 4) {
864 wpa_printf(MSG_INFO, "Too short encrypted data frame");
865 return;
866 }
867
868 keyid = data[3] >> 6;
869 if (keyid != 0) {
870 wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
871 "individually addressed Data frame from " MACSTR,
872 keyid, MAC2STR(hdr->addr2));
873 }
874
2edd5c23
JM
875 if (qos)
876 tid = qos[0] & 0x0f;
877 else
878 tid = 0;
879 if (fc & WLAN_FC_TODS)
880 rsc = sta->rsc_tods[tid];
881 else
882 rsc = sta->rsc_fromds[tid];
883
884
885 ccmp_get_pn(pn, data);
886 if (os_memcmp(pn, rsc, 6) <= 0) {
887 wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: SA=" MACSTR,
888 MAC2STR(hdr->addr2));
889 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
890 wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
891 }
892
d318c534
JM
893 /* TODO: TKIP */
894
895 decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
2edd5c23 896 if (decrypted) {
d318c534 897 rx_data_process(wt, dst, src, decrypted, dlen, 1);
2edd5c23
JM
898 os_memcpy(rsc, pn, 6);
899 }
d318c534 900 os_free(decrypted);
32234bba
JM
901}
902
903
904static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
905 const u8 *qos, const u8 *dst, const u8 *src,
906 const u8 *data, size_t len)
907{
908 u16 fc = le_to_host16(hdr->frame_control);
909 int prot = !!(fc & WLAN_FC_ISWEP);
910
911 if (qos) {
912 u8 ack = (qos[0] & 0x60) >> 5;
913 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
914 " len=%u%s tid=%u%s%s",
915 MAC2STR(src), MAC2STR(dst), (unsigned int) len,
916 prot ? " Prot" : "", qos[0] & 0x0f,
917 (qos[0] & 0x10) ? " EOSP" : "",
918 ack == 0 ? "" :
919 (ack == 1 ? " NoAck" :
920 (ack == 2 ? " NoExpAck" : " BA")));
921 } else {
922 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
923 " len=%u%s",
924 MAC2STR(src), MAC2STR(dst), (unsigned int) len,
925 prot ? " Prot" : "");
926 }
927
928 if (prot)
929 rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
930 else
931 rx_data_process(wt, dst, src, data, len, 0);
932}
933
934
2d73f0a8
JM
935void rx_data(struct wlantest *wt, const u8 *data, size_t len)
936{
937 const struct ieee80211_hdr *hdr;
32234bba
JM
938 u16 fc, stype;
939 size_t hdrlen;
940 const u8 *qos = NULL;
2d73f0a8
JM
941
942 if (len < 24)
943 return;
944
945 hdr = (const struct ieee80211_hdr *) data;
946 fc = le_to_host16(hdr->frame_control);
32234bba
JM
947 stype = WLAN_FC_GET_STYPE(fc);
948 hdrlen = 24;
949 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
950 (WLAN_FC_TODS | WLAN_FC_FROMDS))
951 hdrlen += ETH_ALEN;
952 if (stype & 0x08) {
953 qos = data + hdrlen;
954 hdrlen += 2;
955 }
956 if (len < hdrlen)
957 return;
2d73f0a8
JM
958 wt->rx_data++;
959
960 switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
961 case 0:
962 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
963 MACSTR " BSSID=" MACSTR,
964 data_stype(WLAN_FC_GET_STYPE(fc)),
965 fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
966 fc & WLAN_FC_ISWEP ? " Prot" : "",
967 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
968 MAC2STR(hdr->addr3));
969 break;
970 case WLAN_FC_FROMDS:
971 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
972 " BSSID=" MACSTR " SA=" MACSTR,
973 data_stype(WLAN_FC_GET_STYPE(fc)),
974 fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
975 fc & WLAN_FC_ISWEP ? " Prot" : "",
976 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
977 MAC2STR(hdr->addr3));
32234bba
JM
978 rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
979 data + hdrlen, len - hdrlen);
2d73f0a8
JM
980 break;
981 case WLAN_FC_TODS:
982 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
983 " SA=" MACSTR " DA=" MACSTR,
984 data_stype(WLAN_FC_GET_STYPE(fc)),
985 fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
986 fc & WLAN_FC_ISWEP ? " Prot" : "",
987 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
988 MAC2STR(hdr->addr3));
32234bba
JM
989 rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
990 data + hdrlen, len - hdrlen);
2d73f0a8
JM
991 break;
992 case WLAN_FC_TODS | WLAN_FC_FROMDS:
993 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
994 MACSTR " DA=" MACSTR " SA=" MACSTR,
995 data_stype(WLAN_FC_GET_STYPE(fc)),
996 fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
997 fc & WLAN_FC_ISWEP ? " Prot" : "",
998 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
999 MAC2STR(hdr->addr3),
1000 MAC2STR((const u8 *) (hdr + 1)));
1001 break;
1002 }
1003}