wlantest: Add support for decrypting WEP frames
[mech_eap.git] / wlantest / rx_data.c
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 #include <linux/if_ether.h>
17
18 #include "utils/common.h"
19 #include "common/defs.h"
20 #include "common/ieee802_11_defs.h"
21 #include "wlantest.h"
22
23
24 static const char * data_stype(u16 stype)
25 {
26         switch (stype) {
27         case WLAN_FC_STYPE_DATA:
28                 return "DATA";
29         case WLAN_FC_STYPE_DATA_CFACK:
30                 return "DATA-CFACK";
31         case WLAN_FC_STYPE_DATA_CFPOLL:
32                 return "DATA-CFPOLL";
33         case WLAN_FC_STYPE_DATA_CFACKPOLL:
34                 return "DATA-CFACKPOLL";
35         case WLAN_FC_STYPE_NULLFUNC:
36                 return "NULLFUNC";
37         case WLAN_FC_STYPE_CFACK:
38                 return "CFACK";
39         case WLAN_FC_STYPE_CFPOLL:
40                 return "CFPOLL";
41         case WLAN_FC_STYPE_CFACKPOLL:
42                 return "CFACKPOLL";
43         case WLAN_FC_STYPE_QOS_DATA:
44                 return "QOSDATA";
45         case WLAN_FC_STYPE_QOS_DATA_CFACK:
46                 return "QOSDATA-CFACK";
47         case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
48                 return "QOSDATA-CFPOLL";
49         case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
50                 return "QOSDATA-CFACKPOLL";
51         case WLAN_FC_STYPE_QOS_NULL:
52                 return "QOS-NULL";
53         case WLAN_FC_STYPE_QOS_CFPOLL:
54                 return "QOS-CFPOLL";
55         case WLAN_FC_STYPE_QOS_CFACKPOLL:
56                 return "QOS-CFACKPOLL";
57         }
58         return "??";
59 }
60
61
62 static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
63                         const u8 *sta_addr, const u8 *dst, const u8 *src,
64                         u16 ethertype, const u8 *data, size_t len, int prot)
65 {
66         switch (ethertype) {
67         case ETH_P_PAE:
68                 rx_data_eapol(wt, dst, src, data, len, prot);
69                 break;
70         case ETH_P_IP:
71                 rx_data_ip(wt, bssid, sta_addr, dst, src, data, len);
72                 break;
73         case 0x890d:
74                 rx_data_80211_encap(wt, bssid, sta_addr, dst, src, data, len);
75                 break;
76         }
77 }
78
79
80 static void rx_data_process(struct wlantest *wt, const u8 *bssid,
81                             const u8 *sta_addr,
82                             const u8 *dst, const u8 *src,
83                             const u8 *data, size_t len, int prot)
84 {
85         if (len == 0)
86                 return;
87
88         if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
89                 rx_data_eth(wt, bssid, sta_addr, dst, src,
90                             WPA_GET_BE16(data + 6), data + 8, len - 8, prot);
91                 return;
92         }
93
94         wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
95 }
96
97
98 static void rx_data_bss_prot_group(struct wlantest *wt,
99                                    const struct ieee80211_hdr *hdr,
100                                    const u8 *qos, const u8 *dst, const u8 *src,
101                                    const u8 *data, size_t len)
102 {
103         struct wlantest_bss *bss;
104         int keyid;
105         u8 *decrypted;
106         size_t dlen;
107         u8 pn[6];
108
109         bss = bss_get(wt, hdr->addr2);
110         if (bss == NULL)
111                 return;
112         if (len < 4) {
113                 wpa_printf(MSG_INFO, "Too short group addressed data frame");
114                 return;
115         }
116
117         if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
118             !(data[3] & 0x20)) {
119                     wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
120                                MACSTR " did not have ExtIV bit set to 1",
121                                MAC2STR(bss->bssid));
122                     return;
123         }
124
125         if (bss->group_cipher == WPA_CIPHER_TKIP) {
126                 if (data[3] & 0x1f) {
127                         wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
128                                    "non-zero reserved bit",
129                                    MAC2STR(bss->bssid));
130                 }
131                 if (data[1] != ((data[0] | 0x20) & 0x7f)) {
132                         wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
133                                    "incorrect WEPSeed[1] (was 0x%x, expected "
134                                    "0x%x)",
135                                    MAC2STR(bss->bssid), data[1],
136                                    (data[0] | 0x20) & 0x7f);
137                 }
138         } else if (bss->group_cipher == WPA_CIPHER_CCMP) {
139                 if (data[2] != 0 || (data[3] & 0x1f) != 0) {
140                         wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
141                                    "non-zero reserved bit",
142                                    MAC2STR(bss->bssid));
143                 }
144         }
145
146         keyid = data[3] >> 6;
147         if (bss->gtk_len[keyid] == 0 && bss->group_cipher != WPA_CIPHER_WEP40)
148         {
149                 wpa_printf(MSG_MSGDUMP, "No GTK known to decrypt the frame "
150                            "(A2=" MACSTR " KeyID=%d)",
151                            MAC2STR(hdr->addr2), keyid);
152                 return;
153         }
154
155         if (bss->group_cipher == WPA_CIPHER_TKIP)
156                 tkip_get_pn(pn, data);
157         else if (bss->group_cipher == WPA_CIPHER_WEP40)
158                 goto skip_replay_det;
159         else
160                 ccmp_get_pn(pn, data);
161         if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
162                 u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
163                 wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
164                            " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
165                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
166                            MAC2STR(hdr->addr3),
167                            WLAN_GET_SEQ_SEQ(seq_ctrl),
168                            WLAN_GET_SEQ_FRAG(seq_ctrl));
169                 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
170                 wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
171         }
172
173 skip_replay_det:
174         if (bss->group_cipher == WPA_CIPHER_TKIP)
175                 decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
176                                          &dlen);
177         else if (bss->group_cipher == WPA_CIPHER_WEP40)
178                 decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
179         else
180                 decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
181                                          &dlen);
182         if (decrypted) {
183                 rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
184                                 dlen, 1);
185                 os_memcpy(bss->rsc[keyid], pn, 6);
186                 write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
187                                      decrypted, dlen);
188         }
189         os_free(decrypted);
190 }
191
192
193 static void rx_data_bss_prot(struct wlantest *wt,
194                              const struct ieee80211_hdr *hdr, const u8 *qos,
195                              const u8 *dst, const u8 *src, const u8 *data,
196                              size_t len)
197 {
198         struct wlantest_bss *bss;
199         struct wlantest_sta *sta, *sta2;
200         int keyid;
201         u16 fc = le_to_host16(hdr->frame_control);
202         u8 *decrypted;
203         size_t dlen;
204         int tid;
205         u8 pn[6], *rsc;
206         struct wlantest_tdls *tdls = NULL;
207         const u8 *tk = NULL;
208
209         if (hdr->addr1[0] & 0x01) {
210                 rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
211                 return;
212         }
213
214         if (fc & WLAN_FC_TODS) {
215                 bss = bss_get(wt, hdr->addr1);
216                 if (bss == NULL)
217                         return;
218                 sta = sta_get(bss, hdr->addr2);
219                 if (sta)
220                         sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++;
221         } else if (fc & WLAN_FC_FROMDS) {
222                 bss = bss_get(wt, hdr->addr2);
223                 if (bss == NULL)
224                         return;
225                 sta = sta_get(bss, hdr->addr1);
226         } else {
227                 bss = bss_get(wt, hdr->addr3);
228                 if (bss == NULL)
229                         return;
230                 sta = sta_find(bss, hdr->addr2);
231                 sta2 = sta_find(bss, hdr->addr1);
232                 if (sta == NULL || sta2 == NULL)
233                         return;
234                 dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
235                 {
236                         if ((tdls->init == sta && tdls->resp == sta2) ||
237                             (tdls->init == sta2 && tdls->resp == sta)) {
238                                 if (!tdls->link_up)
239                                         wpa_printf(MSG_DEBUG, "TDLS: Link not "
240                                                    "up, but Data frame seen");
241                                 tk = tdls->tpk.tk;
242                                 break;
243                         }
244                 }
245         }
246         if ((sta == NULL ||
247              (!sta->ptk_set && sta->pairwise_cipher != WPA_CIPHER_WEP40)) &&
248             tk == NULL) {
249                 wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
250                 return;
251         }
252
253         if (len < 4) {
254                 wpa_printf(MSG_INFO, "Too short encrypted data frame");
255                 return;
256         }
257
258         if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
259             !(data[3] & 0x20)) {
260                     wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
261                                MACSTR " did not have ExtIV bit set to 1",
262                                MAC2STR(src));
263                     return;
264         }
265
266         if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) {
267                 if (data[3] & 0x1f) {
268                         wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
269                                    "non-zero reserved bit",
270                                    MAC2STR(hdr->addr2));
271                 }
272                 if (data[1] != ((data[0] | 0x20) & 0x7f)) {
273                         wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
274                                    "incorrect WEPSeed[1] (was 0x%x, expected "
275                                    "0x%x)",
276                                    MAC2STR(hdr->addr2), data[1],
277                                    (data[0] | 0x20) & 0x7f);
278                 }
279         } else if (tk || sta->pairwise_cipher == WPA_CIPHER_CCMP) {
280                 if (data[2] != 0 || (data[3] & 0x1f) != 0) {
281                         wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
282                                    "non-zero reserved bit",
283                                    MAC2STR(hdr->addr2));
284                 }
285         }
286
287         keyid = data[3] >> 6;
288         if (keyid != 0) {
289                 wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
290                            "individually addressed Data frame from " MACSTR,
291                            keyid, MAC2STR(hdr->addr2));
292         }
293
294         if (qos)
295                 tid = qos[0] & 0x0f;
296         else
297                 tid = 0;
298         if (tk) {
299                 if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
300                         rsc = tdls->rsc_init[tid];
301                 else
302                         rsc = tdls->rsc_resp[tid];
303         } else if (fc & WLAN_FC_TODS)
304                 rsc = sta->rsc_tods[tid];
305         else
306                 rsc = sta->rsc_fromds[tid];
307
308
309         if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP)
310                 tkip_get_pn(pn, data);
311         else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
312                 goto skip_replay_det;
313         else
314                 ccmp_get_pn(pn, data);
315         if (os_memcmp(pn, rsc, 6) <= 0) {
316                 u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
317                 wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
318                            " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
319                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
320                            MAC2STR(hdr->addr3),
321                            WLAN_GET_SEQ_SEQ(seq_ctrl),
322                            WLAN_GET_SEQ_FRAG(seq_ctrl));
323                 wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
324                 wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
325         }
326
327 skip_replay_det:
328         if (tk)
329                 decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
330         else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
331                 decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
332         else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
333                 decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
334         else
335                 decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
336         if (decrypted) {
337                 rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
338                                 dlen, 1);
339                 os_memcpy(rsc, pn, 6);
340                 write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
341                                      decrypted, dlen);
342         }
343         os_free(decrypted);
344 }
345
346
347 static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
348                         const u8 *qos, const u8 *dst, const u8 *src,
349                         const u8 *data, size_t len)
350 {
351         u16 fc = le_to_host16(hdr->frame_control);
352         int prot = !!(fc & WLAN_FC_ISWEP);
353
354         if (qos) {
355                 u8 ack = (qos[0] & 0x60) >> 5;
356                 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
357                            " len=%u%s tid=%u%s%s",
358                            MAC2STR(src), MAC2STR(dst), (unsigned int) len,
359                            prot ? " Prot" : "", qos[0] & 0x0f,
360                            (qos[0] & 0x10) ? " EOSP" : "",
361                            ack == 0 ? "" :
362                            (ack == 1 ? " NoAck" :
363                             (ack == 2 ? " NoExpAck" : " BA")));
364         } else {
365                 wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
366                            " len=%u%s",
367                            MAC2STR(src), MAC2STR(dst), (unsigned int) len,
368                            prot ? " Prot" : "");
369         }
370
371         if (prot)
372                 rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
373         else {
374                 const u8 *bssid, *sta_addr;
375                 if (fc & WLAN_FC_TODS) {
376                         bssid = hdr->addr1;
377                         sta_addr = hdr->addr2;
378                 } else {
379                         bssid = hdr->addr2;
380                         sta_addr = hdr->addr1;
381                 }
382                 rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0);
383         }
384 }
385
386
387 static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *bssid,
388                                        const u8 *sta1_addr,
389                                        const u8 *sta2_addr)
390 {
391         struct wlantest_bss *bss;
392         struct wlantest_sta *sta1, *sta2;
393         struct wlantest_tdls *tdls;
394
395         bss = bss_find(wt, bssid);
396         if (bss == NULL)
397                 return NULL;
398         sta1 = sta_find(bss, sta1_addr);
399         if (sta1 == NULL)
400                 return NULL;
401         sta2 = sta_find(bss, sta2_addr);
402         if (sta2 == NULL)
403                 return NULL;
404
405         dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
406                 if ((tdls->init == sta1 && tdls->resp == sta2) ||
407                     (tdls->init == sta2 && tdls->resp == sta1))
408                         return tdls;
409         }
410
411         return NULL;
412 }
413
414
415 static void add_direct_link(struct wlantest *wt, const u8 *bssid,
416                             const u8 *sta1_addr, const u8 *sta2_addr)
417 {
418         struct wlantest_tdls *tdls;
419
420         tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
421         if (tdls == NULL)
422                 return;
423
424         if (tdls->link_up)
425                 tdls->counters[WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK]++;
426         else
427                 tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK]++;
428 }
429
430
431 static void add_ap_path(struct wlantest *wt, const u8 *bssid,
432                         const u8 *sta1_addr, const u8 *sta2_addr)
433 {
434         struct wlantest_tdls *tdls;
435
436         tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
437         if (tdls == NULL)
438                 return;
439
440         if (tdls->link_up)
441                 tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_AP_PATH]++;
442         else
443                 tdls->counters[WLANTEST_TDLS_COUNTER_VALID_AP_PATH]++;
444 }
445
446
447 void rx_data(struct wlantest *wt, const u8 *data, size_t len)
448 {
449         const struct ieee80211_hdr *hdr;
450         u16 fc, stype;
451         size_t hdrlen;
452         const u8 *qos = NULL;
453
454         if (len < 24)
455                 return;
456
457         hdr = (const struct ieee80211_hdr *) data;
458         fc = le_to_host16(hdr->frame_control);
459         stype = WLAN_FC_GET_STYPE(fc);
460         hdrlen = 24;
461         if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
462             (WLAN_FC_TODS | WLAN_FC_FROMDS))
463                 hdrlen += ETH_ALEN;
464         if (stype & 0x08) {
465                 qos = data + hdrlen;
466                 hdrlen += 2;
467         }
468         if (len < hdrlen)
469                 return;
470         wt->rx_data++;
471
472         switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
473         case 0:
474                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
475                            MACSTR " BSSID=" MACSTR,
476                            data_stype(WLAN_FC_GET_STYPE(fc)),
477                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
478                            fc & WLAN_FC_ISWEP ? " Prot" : "",
479                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
480                            MAC2STR(hdr->addr3));
481                 add_direct_link(wt, hdr->addr3, hdr->addr1, hdr->addr2);
482                 rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
483                             data + hdrlen, len - hdrlen);
484                 break;
485         case WLAN_FC_FROMDS:
486                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
487                            " BSSID=" MACSTR " SA=" MACSTR,
488                            data_stype(WLAN_FC_GET_STYPE(fc)),
489                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
490                            fc & WLAN_FC_ISWEP ? " Prot" : "",
491                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
492                            MAC2STR(hdr->addr3));
493                 add_ap_path(wt, hdr->addr2, hdr->addr1, hdr->addr3);
494                 rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
495                             data + hdrlen, len - hdrlen);
496                 break;
497         case WLAN_FC_TODS:
498                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
499                            " SA=" MACSTR " DA=" MACSTR,
500                            data_stype(WLAN_FC_GET_STYPE(fc)),
501                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
502                            fc & WLAN_FC_ISWEP ? " Prot" : "",
503                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
504                            MAC2STR(hdr->addr3));
505                 add_ap_path(wt, hdr->addr1, hdr->addr3, hdr->addr2);
506                 rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
507                             data + hdrlen, len - hdrlen);
508                 break;
509         case WLAN_FC_TODS | WLAN_FC_FROMDS:
510                 wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
511                            MACSTR " DA=" MACSTR " SA=" MACSTR,
512                            data_stype(WLAN_FC_GET_STYPE(fc)),
513                            fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
514                            fc & WLAN_FC_ISWEP ? " Prot" : "",
515                            MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
516                            MAC2STR(hdr->addr3),
517                            MAC2STR((const u8 *) (hdr + 1)));
518                 break;
519         }
520 }