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