wlantest: Add TDLS entry on TDLS Setup Request
[mech_eap.git] / wlantest / inject.c
1 /*
2  * wlantest frame injection
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"
18 #include "common/defs.h"
19 #include "common/ieee802_11_defs.h"
20 #include "crypto/aes_wrap.h"
21 #include "wlantest.h"
22
23
24 static int inject_frame(int s, const void *data, size_t len)
25 {
26 #define IEEE80211_RADIOTAP_F_FRAG       0x08
27         unsigned char rtap_hdr[] = {
28                 0x00, 0x00, /* radiotap version */
29                 0x0e, 0x00, /* radiotap length */
30                 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
31                 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
32                 0x00,       /* padding */
33                 0x00, 0x00, /* RX and TX flags to indicate that */
34                 0x00, 0x00, /* this is the injected frame directly */
35         };
36         struct iovec iov[2] = {
37                 {
38                         .iov_base = &rtap_hdr,
39                         .iov_len = sizeof(rtap_hdr),
40                 },
41                 {
42                         .iov_base = (void *) data,
43                         .iov_len = len,
44                 }
45         };
46         struct msghdr msg = {
47                 .msg_name = NULL,
48                 .msg_namelen = 0,
49                 .msg_iov = iov,
50                 .msg_iovlen = 2,
51                 .msg_control = NULL,
52                 .msg_controllen = 0,
53                 .msg_flags = 0,
54         };
55         int ret;
56
57         ret = sendmsg(s, &msg, 0);
58         if (ret < 0)
59                 perror("sendmsg");
60         return ret;
61 }
62
63
64 static int is_robust_mgmt(u8 *frame, size_t len)
65 {
66         struct ieee80211_mgmt *mgmt;
67         u16 fc, stype;
68         if (len < 24)
69                 return 0;
70         mgmt = (struct ieee80211_mgmt *) frame;
71         fc = le_to_host16(mgmt->frame_control);
72         if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
73                 return 0;
74         stype = WLAN_FC_GET_STYPE(fc);
75         if (stype == WLAN_FC_STYPE_DEAUTH || stype == WLAN_FC_STYPE_DISASSOC)
76                 return 1;
77         if (stype == WLAN_FC_STYPE_ACTION) {
78                 if (len < 25)
79                         return 0;
80                 if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
81                         return 1;
82         }
83         return 0;
84 }
85
86
87 static int wlantest_inject_bip(struct wlantest *wt, struct wlantest_bss *bss,
88                                u8 *frame, size_t len, int incorrect_key)
89 {
90         u8 *prot, *pos, *buf;
91         u8 mic[16];
92         u8 dummy[16];
93         int ret;
94         u16 fc;
95         struct ieee80211_hdr *hdr;
96         size_t plen;
97
98         if (!bss->igtk_set[bss->igtk_idx])
99                 return -1;
100
101         plen = len + 18;
102         prot = os_malloc(plen);
103         if (prot == NULL)
104                 return -1;
105         os_memcpy(prot, frame, len);
106         pos = prot + len;
107         *pos++ = WLAN_EID_MMIE;
108         *pos++ = 16;
109         WPA_PUT_LE16(pos, bss->igtk_idx);
110         pos += 2;
111         inc_byte_array(bss->ipn[bss->igtk_idx], 6);
112         os_memcpy(pos, bss->ipn[bss->igtk_idx], 6);
113         pos += 6;
114         os_memset(pos, 0, 8); /* MIC */
115
116         buf = os_malloc(plen + 20 - 24);
117         if (buf == NULL) {
118                 os_free(prot);
119                 return -1;
120         }
121
122         /* BIP AAD: FC(masked) A1 A2 A3 */
123         hdr = (struct ieee80211_hdr *) frame;
124         fc = le_to_host16(hdr->frame_control);
125         fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
126         WPA_PUT_LE16(buf, fc);
127         os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
128         os_memcpy(buf + 20, prot + 24, plen - 24);
129         wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, plen + 20 - 24);
130         /* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
131         os_memset(dummy, 0x11, sizeof(dummy));
132         if (omac1_aes_128(incorrect_key ? dummy : bss->igtk[bss->igtk_idx],
133                           buf, plen + 20 - 24, mic) < 0) {
134                 os_free(prot);
135                 os_free(buf);
136                 return -1;
137         }
138         os_free(buf);
139
140         os_memcpy(pos, mic, 8);
141         wpa_hexdump(MSG_DEBUG, "BIP MMIE MIC", pos, 8);
142
143         ret = inject_frame(wt->monitor_sock, prot, plen);
144         os_free(prot);
145
146         return (ret < 0) ? -1 : 0;
147 }
148
149
150 static int wlantest_inject_prot_bc(struct wlantest *wt,
151                                    struct wlantest_bss *bss,
152                                    u8 *frame, size_t len, int incorrect_key)
153 {
154         u8 *crypt;
155         size_t crypt_len;
156         int ret;
157         u8 dummy[64];
158         u8 *pn;
159         struct ieee80211_hdr *hdr;
160         u16 fc;
161         int hdrlen;
162
163         hdr = (struct ieee80211_hdr *) frame;
164         hdrlen = 24;
165         fc = le_to_host16(hdr->frame_control);
166
167         if (!bss->gtk_len[bss->gtk_idx])
168                 return -1;
169
170         if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
171             (WLAN_FC_TODS | WLAN_FC_FROMDS))
172                 hdrlen += ETH_ALEN;
173         pn = bss->rsc[bss->gtk_idx];
174         inc_byte_array(pn, 6);
175
176         os_memset(dummy, 0x11, sizeof(dummy));
177         if (bss->group_cipher == WPA_CIPHER_TKIP)
178                 crypt = tkip_encrypt(incorrect_key ? dummy :
179                                      bss->gtk[bss->gtk_idx],
180                                      frame, len, hdrlen, NULL, pn,
181                                      bss->gtk_idx, &crypt_len);
182         else
183                 crypt = ccmp_encrypt(incorrect_key ? dummy :
184                                      bss->gtk[bss->gtk_idx],
185                                      frame, len, hdrlen, NULL, pn,
186                                      bss->gtk_idx, &crypt_len);
187
188         if (crypt == NULL)
189                 return -1;
190
191         ret = inject_frame(wt->monitor_sock, crypt, crypt_len);
192         os_free(crypt);
193
194         return (ret < 0) ? -1 : 0;
195 }
196
197
198 static int wlantest_inject_prot(struct wlantest *wt, struct wlantest_bss *bss,
199                                 struct wlantest_sta *sta, u8 *frame,
200                                 size_t len, int incorrect_key)
201 {
202         u8 *crypt;
203         size_t crypt_len;
204         int ret;
205         u8 dummy[64];
206         u8 *pn;
207         struct ieee80211_hdr *hdr;
208         u16 fc;
209         int tid = 0;
210         u8 *qos = NULL;
211         int hdrlen;
212         struct wlantest_tdls *tdls = NULL;
213         const u8 *tk = NULL;
214
215         hdr = (struct ieee80211_hdr *) frame;
216         hdrlen = 24;
217         fc = le_to_host16(hdr->frame_control);
218
219         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
220             (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 0) {
221                 struct wlantest_sta *sta2;
222                 bss = bss_get(wt, hdr->addr3);
223                 if (bss == NULL) {
224                         wpa_printf(MSG_DEBUG, "No BSS found for TDLS "
225                                    "injection");
226                         return -1;
227                 }
228                 sta = sta_find(bss, hdr->addr2);
229                 sta2 = sta_find(bss, hdr->addr1);
230                 if (sta == NULL || sta2 == NULL) {
231                         wpa_printf(MSG_DEBUG, "No stations found for TDLS "
232                                    "injection");
233                         return -1;
234                 }
235                 dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
236                 {
237                         if ((tdls->init == sta && tdls->resp == sta2) ||
238                             (tdls->init == sta2 && tdls->resp == sta)) {
239                                 if (!tdls->link_up)
240                                         wpa_printf(MSG_DEBUG, "TDLS: Link not "
241                                                    "up, but injecting Data "
242                                                    "frame on direct link");
243                                 tk = tdls->tpk.tk;
244                                 break;
245                         }
246                 }
247         }
248
249         if (tk == NULL && sta == NULL) {
250                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
251                         return wlantest_inject_bip(wt, bss, frame, len,
252                                                    incorrect_key);
253                 return wlantest_inject_prot_bc(wt, bss, frame, len,
254                                                incorrect_key);
255         }
256
257         if (tk == NULL && !sta->ptk_set) {
258                 wpa_printf(MSG_DEBUG, "No key known for injection");
259                 return -1;
260         }
261
262         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
263                 tid = 16;
264         else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
265                 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
266                     (WLAN_FC_TODS | WLAN_FC_FROMDS))
267                         hdrlen += ETH_ALEN;
268                 if (WLAN_FC_GET_STYPE(fc) & 0x08) {
269                         qos = frame + hdrlen;
270                         hdrlen += 2;
271                         tid = qos[0] & 0x0f;
272                 }
273         }
274         if (tk) {
275                 if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
276                         pn = tdls->rsc_init[tid];
277                 else
278                         pn = tdls->rsc_resp[tid];
279         } else if (os_memcmp(hdr->addr2, bss->bssid, ETH_ALEN) == 0)
280                 pn = sta->rsc_fromds[tid];
281         else
282                 pn = sta->rsc_tods[tid];
283         inc_byte_array(pn, 6);
284
285         os_memset(dummy, 0x11, sizeof(dummy));
286         if (tk) 
287                 crypt = ccmp_encrypt(incorrect_key ? dummy : tk,
288                                      frame, len, hdrlen, qos, pn, 0,
289                                      &crypt_len);
290         else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
291                 crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
292                                      frame, len, hdrlen, qos, pn, 0,
293                                      &crypt_len);
294         else
295                 crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
296                                      frame, len, hdrlen, qos, pn, 0,
297                                      &crypt_len);
298
299         if (crypt == NULL) {
300                 wpa_printf(MSG_DEBUG, "Frame encryption failed");
301                 return -1;
302         }
303
304         wpa_hexdump(MSG_DEBUG, "Inject frame (encrypted)", crypt, crypt_len);
305         ret = inject_frame(wt->monitor_sock, crypt, crypt_len);
306         os_free(crypt);
307         wpa_printf(MSG_DEBUG, "inject_frame for protected frame: %d", ret);
308
309         return (ret < 0) ? -1 : 0;
310 }
311
312
313 int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
314                     struct wlantest_sta *sta, u8 *frame, size_t len,
315                     enum wlantest_inject_protection prot)
316 {
317         int ret;
318         struct ieee80211_hdr *hdr;
319         u16 fc;
320         int protectable, protect = 0;
321
322         wpa_hexdump(MSG_DEBUG, "Inject frame", frame, len);
323         if (wt->monitor_sock < 0) {
324                 wpa_printf(MSG_INFO, "Cannot inject frames when monitor "
325                            "interface is not in use");
326                 return -1;
327         }
328
329         hdr = (struct ieee80211_hdr *) frame;
330         fc = le_to_host16(hdr->frame_control);
331         protectable = WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ||
332                 is_robust_mgmt(frame, len);
333
334         if (prot == WLANTEST_INJECT_PROTECTED ||
335             prot == WLANTEST_INJECT_INCORRECT_KEY) {
336                 if (!sta &&
337                     ((WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
338                       !bss->igtk_set[bss->igtk_idx]) ||
339                      (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
340                       !bss->gtk_len[bss->gtk_idx]))) {
341                         wpa_printf(MSG_INFO, "No GTK/IGTK known for "
342                                    MACSTR " to protect the injected "
343                                    "frame", MAC2STR(bss->bssid));
344                         return -1;
345                 }
346                 if (sta && !sta->ptk_set) {
347                         wpa_printf(MSG_INFO, "No PTK known for the STA " MACSTR
348                                    " to encrypt the injected frame",
349                                    MAC2STR(sta->addr));
350                         return -1;
351                 }
352                 protect = 1;
353         } else if (protectable && prot != WLANTEST_INJECT_UNPROTECTED) {
354                 if (sta && sta->ptk_set)
355                         protect = 1;
356                 else if (!sta) {
357                         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
358                             bss->gtk_len[bss->gtk_idx])
359                                 protect = 1;
360                         if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
361                             bss->igtk_set[bss->igtk_idx])
362                                 protect = 1;
363                 }
364         }
365
366         if (protect)
367                 return wlantest_inject_prot(
368                         wt, bss, sta, frame, len,
369                         prot == WLANTEST_INJECT_INCORRECT_KEY);
370
371         ret = inject_frame(wt->monitor_sock, frame, len);
372         wpa_printf(MSG_DEBUG, "inject_frame for unprotected frame: %d", ret);
373         return (ret < 0) ? -1 : 0;
374 }