• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hostapd - IEEE 802.11r - Fast BSS Transition
3  * Copyright (c) 2004-2014, 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 "utils/eloop.h"
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "crypto/aes_wrap.h"
16 #include "crypto/random.h"
17 #include "ap_config.h"
18 #include "ieee802_11.h"
19 #include "wmm.h"
20 #include "wpa_auth.h"
21 #include "wpa_auth_i.h"
22 
23 
24 #ifdef CONFIG_IEEE80211R
25 
26 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
27 				     const u8 *current_ap, const u8 *sta_addr,
28 				     u16 status, const u8 *resp_ies,
29 				     size_t resp_ies_len);
30 
31 
wpa_ft_rrb_send(struct wpa_authenticator * wpa_auth,const u8 * dst,const u8 * data,size_t data_len)32 static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
33 			   const u8 *data, size_t data_len)
34 {
35 	if (wpa_auth->cb.send_ether == NULL)
36 		return -1;
37 	wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst));
38 	return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB,
39 				       data, data_len);
40 }
41 
42 
wpa_ft_action_send(struct wpa_authenticator * wpa_auth,const u8 * dst,const u8 * data,size_t data_len)43 static int wpa_ft_action_send(struct wpa_authenticator *wpa_auth,
44 			      const u8 *dst, const u8 *data, size_t data_len)
45 {
46 	if (wpa_auth->cb.send_ft_action == NULL)
47 		return -1;
48 	return wpa_auth->cb.send_ft_action(wpa_auth->cb.ctx, dst,
49 					   data, data_len);
50 }
51 
52 
53 static struct wpa_state_machine *
wpa_ft_add_sta(struct wpa_authenticator * wpa_auth,const u8 * sta_addr)54 wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
55 {
56 	if (wpa_auth->cb.add_sta == NULL)
57 		return NULL;
58 	return wpa_auth->cb.add_sta(wpa_auth->cb.ctx, sta_addr);
59 }
60 
61 
wpa_ft_add_tspec(struct wpa_authenticator * wpa_auth,const u8 * sta_addr,u8 * tspec_ie,size_t tspec_ielen)62 static int wpa_ft_add_tspec(struct wpa_authenticator *wpa_auth,
63 			    const u8 *sta_addr,
64 			    u8 *tspec_ie, size_t tspec_ielen)
65 {
66 	if (wpa_auth->cb.add_tspec == NULL) {
67 		wpa_printf(MSG_DEBUG, "FT: add_tspec is not initialized");
68 		return -1;
69 	}
70 	return wpa_auth->cb.add_tspec(wpa_auth->cb.ctx, sta_addr, tspec_ie,
71 				      tspec_ielen);
72 }
73 
74 
wpa_write_mdie(struct wpa_auth_config * conf,u8 * buf,size_t len)75 int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
76 {
77 	u8 *pos = buf;
78 	u8 capab;
79 	if (len < 2 + sizeof(struct rsn_mdie))
80 		return -1;
81 
82 	*pos++ = WLAN_EID_MOBILITY_DOMAIN;
83 	*pos++ = MOBILITY_DOMAIN_ID_LEN + 1;
84 	os_memcpy(pos, conf->mobility_domain, MOBILITY_DOMAIN_ID_LEN);
85 	pos += MOBILITY_DOMAIN_ID_LEN;
86 	capab = 0;
87 	if (conf->ft_over_ds)
88 		capab |= RSN_FT_CAPAB_FT_OVER_DS;
89 	*pos++ = capab;
90 
91 	return pos - buf;
92 }
93 
94 
wpa_write_ftie(struct wpa_auth_config * conf,const u8 * r0kh_id,size_t r0kh_id_len,const u8 * anonce,const u8 * snonce,u8 * buf,size_t len,const u8 * subelem,size_t subelem_len)95 int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
96 		   size_t r0kh_id_len,
97 		   const u8 *anonce, const u8 *snonce,
98 		   u8 *buf, size_t len, const u8 *subelem,
99 		   size_t subelem_len)
100 {
101 	u8 *pos = buf, *ielen;
102 	struct rsn_ftie *hdr;
103 
104 	if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
105 	    subelem_len)
106 		return -1;
107 
108 	*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
109 	ielen = pos++;
110 
111 	hdr = (struct rsn_ftie *) pos;
112 	os_memset(hdr, 0, sizeof(*hdr));
113 	pos += sizeof(*hdr);
114 	WPA_PUT_LE16(hdr->mic_control, 0);
115 	if (anonce)
116 		os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
117 	if (snonce)
118 		os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
119 
120 	/* Optional Parameters */
121 	*pos++ = FTIE_SUBELEM_R1KH_ID;
122 	*pos++ = FT_R1KH_ID_LEN;
123 	os_memcpy(pos, conf->r1_key_holder, FT_R1KH_ID_LEN);
124 	pos += FT_R1KH_ID_LEN;
125 
126 	if (r0kh_id) {
127 		*pos++ = FTIE_SUBELEM_R0KH_ID;
128 		*pos++ = r0kh_id_len;
129 		os_memcpy(pos, r0kh_id, r0kh_id_len);
130 		pos += r0kh_id_len;
131 	}
132 
133 	if (subelem) {
134 		os_memcpy(pos, subelem, subelem_len);
135 		pos += subelem_len;
136 	}
137 
138 	*ielen = pos - buf - 2;
139 
140 	return pos - buf;
141 }
142 
143 
144 struct wpa_ft_pmk_r0_sa {
145 	struct wpa_ft_pmk_r0_sa *next;
146 	u8 pmk_r0[PMK_LEN];
147 	u8 pmk_r0_name[WPA_PMK_NAME_LEN];
148 	u8 spa[ETH_ALEN];
149 	int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */
150 	/* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
151 	int pmk_r1_pushed;
152 };
153 
154 struct wpa_ft_pmk_r1_sa {
155 	struct wpa_ft_pmk_r1_sa *next;
156 	u8 pmk_r1[PMK_LEN];
157 	u8 pmk_r1_name[WPA_PMK_NAME_LEN];
158 	u8 spa[ETH_ALEN];
159 	int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */
160 	/* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
161 };
162 
163 struct wpa_ft_pmk_cache {
164 	struct wpa_ft_pmk_r0_sa *pmk_r0;
165 	struct wpa_ft_pmk_r1_sa *pmk_r1;
166 };
167 
wpa_ft_pmk_cache_init(void)168 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void)
169 {
170 	struct wpa_ft_pmk_cache *cache;
171 
172 	cache = os_zalloc(sizeof(*cache));
173 
174 	return cache;
175 }
176 
177 
wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache * cache)178 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache)
179 {
180 	struct wpa_ft_pmk_r0_sa *r0, *r0prev;
181 	struct wpa_ft_pmk_r1_sa *r1, *r1prev;
182 
183 	r0 = cache->pmk_r0;
184 	while (r0) {
185 		r0prev = r0;
186 		r0 = r0->next;
187 		os_memset(r0prev->pmk_r0, 0, PMK_LEN);
188 		os_free(r0prev);
189 	}
190 
191 	r1 = cache->pmk_r1;
192 	while (r1) {
193 		r1prev = r1;
194 		r1 = r1->next;
195 		os_memset(r1prev->pmk_r1, 0, PMK_LEN);
196 		os_free(r1prev);
197 	}
198 
199 	os_free(cache);
200 }
201 
202 
wpa_ft_store_pmk_r0(struct wpa_authenticator * wpa_auth,const u8 * spa,const u8 * pmk_r0,const u8 * pmk_r0_name,int pairwise)203 static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth,
204 			       const u8 *spa, const u8 *pmk_r0,
205 			       const u8 *pmk_r0_name, int pairwise)
206 {
207 	struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
208 	struct wpa_ft_pmk_r0_sa *r0;
209 
210 	/* TODO: add expiration and limit on number of entries in cache */
211 
212 	r0 = os_zalloc(sizeof(*r0));
213 	if (r0 == NULL)
214 		return -1;
215 
216 	os_memcpy(r0->pmk_r0, pmk_r0, PMK_LEN);
217 	os_memcpy(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
218 	os_memcpy(r0->spa, spa, ETH_ALEN);
219 	r0->pairwise = pairwise;
220 
221 	r0->next = cache->pmk_r0;
222 	cache->pmk_r0 = r0;
223 
224 	return 0;
225 }
226 
227 
wpa_ft_fetch_pmk_r0(struct wpa_authenticator * wpa_auth,const u8 * spa,const u8 * pmk_r0_name,u8 * pmk_r0,int * pairwise)228 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth,
229 			       const u8 *spa, const u8 *pmk_r0_name,
230 			       u8 *pmk_r0, int *pairwise)
231 {
232 	struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
233 	struct wpa_ft_pmk_r0_sa *r0;
234 
235 	r0 = cache->pmk_r0;
236 	while (r0) {
237 		if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 &&
238 		    os_memcmp_const(r0->pmk_r0_name, pmk_r0_name,
239 				    WPA_PMK_NAME_LEN) == 0) {
240 			os_memcpy(pmk_r0, r0->pmk_r0, PMK_LEN);
241 			if (pairwise)
242 				*pairwise = r0->pairwise;
243 			return 0;
244 		}
245 
246 		r0 = r0->next;
247 	}
248 
249 	return -1;
250 }
251 
252 
wpa_ft_store_pmk_r1(struct wpa_authenticator * wpa_auth,const u8 * spa,const u8 * pmk_r1,const u8 * pmk_r1_name,int pairwise)253 static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth,
254 			       const u8 *spa, const u8 *pmk_r1,
255 			       const u8 *pmk_r1_name, int pairwise)
256 {
257 	struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
258 	struct wpa_ft_pmk_r1_sa *r1;
259 
260 	/* TODO: add expiration and limit on number of entries in cache */
261 
262 	r1 = os_zalloc(sizeof(*r1));
263 	if (r1 == NULL)
264 		return -1;
265 
266 	os_memcpy(r1->pmk_r1, pmk_r1, PMK_LEN);
267 	os_memcpy(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
268 	os_memcpy(r1->spa, spa, ETH_ALEN);
269 	r1->pairwise = pairwise;
270 
271 	r1->next = cache->pmk_r1;
272 	cache->pmk_r1 = r1;
273 
274 	return 0;
275 }
276 
277 
wpa_ft_fetch_pmk_r1(struct wpa_authenticator * wpa_auth,const u8 * spa,const u8 * pmk_r1_name,u8 * pmk_r1,int * pairwise)278 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
279 			       const u8 *spa, const u8 *pmk_r1_name,
280 			       u8 *pmk_r1, int *pairwise)
281 {
282 	struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
283 	struct wpa_ft_pmk_r1_sa *r1;
284 
285 	r1 = cache->pmk_r1;
286 	while (r1) {
287 		if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 &&
288 		    os_memcmp_const(r1->pmk_r1_name, pmk_r1_name,
289 				    WPA_PMK_NAME_LEN) == 0) {
290 			os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN);
291 			if (pairwise)
292 				*pairwise = r1->pairwise;
293 			return 0;
294 		}
295 
296 		r1 = r1->next;
297 	}
298 
299 	return -1;
300 }
301 
302 
wpa_ft_pull_pmk_r1(struct wpa_state_machine * sm,const u8 * ies,size_t ies_len,const u8 * pmk_r0_name)303 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
304 			      const u8 *ies, size_t ies_len,
305 			      const u8 *pmk_r0_name)
306 {
307 	struct ft_remote_r0kh *r0kh;
308 	struct ft_r0kh_r1kh_pull_frame frame, f;
309 
310 	r0kh = sm->wpa_auth->conf.r0kh_list;
311 	while (r0kh) {
312 		if (r0kh->id_len == sm->r0kh_id_len &&
313 		    os_memcmp_const(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) ==
314 		    0)
315 			break;
316 		r0kh = r0kh->next;
317 	}
318 	if (r0kh == NULL) {
319 		wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID",
320 			    sm->r0kh_id, sm->r0kh_id_len);
321 		return -1;
322 	}
323 
324 	wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
325 		   "address " MACSTR, MAC2STR(r0kh->addr));
326 
327 	os_memset(&frame, 0, sizeof(frame));
328 	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
329 	frame.packet_type = FT_PACKET_R0KH_R1KH_PULL;
330 	frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN);
331 	os_memcpy(frame.ap_address, sm->wpa_auth->addr, ETH_ALEN);
332 
333 	/* aes_wrap() does not support inplace encryption, so use a temporary
334 	 * buffer for the data. */
335 	if (random_get_bytes(f.nonce, FT_R0KH_R1KH_PULL_NONCE_LEN)) {
336 		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
337 			   "nonce");
338 		return -1;
339 	}
340 	os_memcpy(sm->ft_pending_pull_nonce, f.nonce,
341 		  FT_R0KH_R1KH_PULL_NONCE_LEN);
342 	os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
343 	os_memcpy(f.r1kh_id, sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
344 	os_memcpy(f.s1kh_id, sm->addr, ETH_ALEN);
345 	os_memset(f.pad, 0, sizeof(f.pad));
346 
347 	if (aes_wrap(r0kh->key, sizeof(r0kh->key),
348 		     (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
349 		     f.nonce, frame.nonce) < 0)
350 		return -1;
351 
352 	wpabuf_free(sm->ft_pending_req_ies);
353 	sm->ft_pending_req_ies = wpabuf_alloc_copy(ies, ies_len);
354 	if (sm->ft_pending_req_ies == NULL)
355 		return -1;
356 
357 	wpa_ft_rrb_send(sm->wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame));
358 
359 	return 0;
360 }
361 
362 
wpa_auth_derive_ptk_ft(struct wpa_state_machine * sm,const u8 * pmk,struct wpa_ptk * ptk,size_t ptk_len)363 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
364 			   struct wpa_ptk *ptk, size_t ptk_len)
365 {
366 	u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
367 	u8 pmk_r1[PMK_LEN];
368 	u8 ptk_name[WPA_PMK_NAME_LEN];
369 	const u8 *mdid = sm->wpa_auth->conf.mobility_domain;
370 	const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder;
371 	size_t r0kh_len = sm->wpa_auth->conf.r0_key_holder_len;
372 	const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder;
373 	const u8 *ssid = sm->wpa_auth->conf.ssid;
374 	size_t ssid_len = sm->wpa_auth->conf.ssid_len;
375 
376 
377 	if (sm->xxkey_len == 0) {
378 		wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
379 			   "derivation");
380 		return -1;
381 	}
382 
383 	wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid,
384 			  r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name);
385 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
386 	wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
387 	wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name,
388 			    sm->pairwise);
389 
390 	wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
391 			  pmk_r1, sm->pmk_r1_name);
392 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
393 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name,
394 		    WPA_PMK_NAME_LEN);
395 	wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, sm->pmk_r1_name,
396 			    sm->pairwise);
397 
398 	wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
399 			  sm->wpa_auth->addr, sm->pmk_r1_name,
400 			  (u8 *) ptk, ptk_len, ptk_name);
401 	wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len);
402 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
403 
404 	return 0;
405 }
406 
407 
wpa_auth_get_seqnum(struct wpa_authenticator * wpa_auth,const u8 * addr,int idx,u8 * seq)408 static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
409 				      const u8 *addr, int idx, u8 *seq)
410 {
411 	if (wpa_auth->cb.get_seqnum == NULL)
412 		return -1;
413 	return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
414 }
415 
416 
wpa_ft_gtk_subelem(struct wpa_state_machine * sm,size_t * len)417 static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
418 {
419 	u8 *subelem;
420 	struct wpa_group *gsm = sm->group;
421 	size_t subelem_len, pad_len;
422 	const u8 *key;
423 	size_t key_len;
424 	u8 keybuf[32];
425 
426 	key_len = gsm->GTK_len;
427 	if (key_len > sizeof(keybuf))
428 		return NULL;
429 
430 	/*
431 	 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
432 	 * than 16 bytes.
433 	 */
434 	pad_len = key_len % 8;
435 	if (pad_len)
436 		pad_len = 8 - pad_len;
437 	if (key_len + pad_len < 16)
438 		pad_len += 8;
439 	if (pad_len && key_len < sizeof(keybuf)) {
440 		os_memcpy(keybuf, gsm->GTK[gsm->GN - 1], key_len);
441 		os_memset(keybuf + key_len, 0, pad_len);
442 		keybuf[key_len] = 0xdd;
443 		key_len += pad_len;
444 		key = keybuf;
445 	} else
446 		key = gsm->GTK[gsm->GN - 1];
447 
448 	/*
449 	 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
450 	 * Key[5..32].
451 	 */
452 	subelem_len = 13 + key_len + 8;
453 	subelem = os_zalloc(subelem_len);
454 	if (subelem == NULL)
455 		return NULL;
456 
457 	subelem[0] = FTIE_SUBELEM_GTK;
458 	subelem[1] = 11 + key_len + 8;
459 	/* Key ID in B0-B1 of Key Info */
460 	WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
461 	subelem[4] = gsm->GTK_len;
462 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
463 	if (aes_wrap(sm->PTK.kek, 16, key_len / 8, key, subelem + 13)) {
464 		os_free(subelem);
465 		return NULL;
466 	}
467 
468 	*len = subelem_len;
469 	return subelem;
470 }
471 
472 
473 #ifdef CONFIG_IEEE80211W
wpa_ft_igtk_subelem(struct wpa_state_machine * sm,size_t * len)474 static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
475 {
476 	u8 *subelem, *pos;
477 	struct wpa_group *gsm = sm->group;
478 	size_t subelem_len;
479 
480 	/* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
481 	 * Key[16+8] */
482 	subelem_len = 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN + 8;
483 	subelem = os_zalloc(subelem_len);
484 	if (subelem == NULL)
485 		return NULL;
486 
487 	pos = subelem;
488 	*pos++ = FTIE_SUBELEM_IGTK;
489 	*pos++ = subelem_len - 2;
490 	WPA_PUT_LE16(pos, gsm->GN_igtk);
491 	pos += 2;
492 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
493 	pos += 6;
494 	*pos++ = WPA_IGTK_LEN;
495 	if (aes_wrap(sm->PTK.kek, 16, WPA_IGTK_LEN / 8,
496 		     gsm->IGTK[gsm->GN_igtk - 4], pos)) {
497 		os_free(subelem);
498 		return NULL;
499 	}
500 
501 	*len = subelem_len;
502 	return subelem;
503 }
504 #endif /* CONFIG_IEEE80211W */
505 
506 
wpa_ft_process_rdie(struct wpa_state_machine * sm,u8 * pos,u8 * end,u8 id,u8 descr_count,const u8 * ies,size_t ies_len)507 static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm,
508 				u8 *pos, u8 *end, u8 id, u8 descr_count,
509 				const u8 *ies, size_t ies_len)
510 {
511 	struct ieee802_11_elems parse;
512 	struct rsn_rdie *rdie;
513 
514 	wpa_printf(MSG_DEBUG, "FT: Resource Request: id=%d descr_count=%d",
515 		   id, descr_count);
516 	wpa_hexdump(MSG_MSGDUMP, "FT: Resource descriptor IE(s)",
517 		    ies, ies_len);
518 
519 	if (end - pos < (int) sizeof(*rdie)) {
520 		wpa_printf(MSG_ERROR, "FT: Not enough room for response RDIE");
521 		return pos;
522 	}
523 
524 	*pos++ = WLAN_EID_RIC_DATA;
525 	*pos++ = sizeof(*rdie);
526 	rdie = (struct rsn_rdie *) pos;
527 	rdie->id = id;
528 	rdie->descr_count = 0;
529 	rdie->status_code = host_to_le16(WLAN_STATUS_SUCCESS);
530 	pos += sizeof(*rdie);
531 
532 	if (ieee802_11_parse_elems((u8 *) ies, ies_len, &parse, 1) ==
533 	    ParseFailed) {
534 		wpa_printf(MSG_DEBUG, "FT: Failed to parse request IEs");
535 		rdie->status_code =
536 			host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
537 		return pos;
538 	}
539 
540 #ifdef NEED_AP_MLME
541 	if (parse.wmm_tspec && sm->wpa_auth->conf.ap_mlme) {
542 		struct wmm_tspec_element *tspec;
543 		int res;
544 
545 		if (parse.wmm_tspec_len + 2 < (int) sizeof(*tspec)) {
546 			wpa_printf(MSG_DEBUG, "FT: Too short WMM TSPEC IE "
547 				   "(%d)", (int) parse.wmm_tspec_len);
548 			rdie->status_code =
549 				host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
550 			return pos;
551 		}
552 		if (end - pos < (int) sizeof(*tspec)) {
553 			wpa_printf(MSG_ERROR, "FT: Not enough room for "
554 				   "response TSPEC");
555 			rdie->status_code =
556 				host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
557 			return pos;
558 		}
559 		tspec = (struct wmm_tspec_element *) pos;
560 		os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec));
561 		res = wmm_process_tspec(tspec);
562 		wpa_printf(MSG_DEBUG, "FT: ADDTS processing result: %d", res);
563 		if (res == WMM_ADDTS_STATUS_INVALID_PARAMETERS)
564 			rdie->status_code =
565 				host_to_le16(WLAN_STATUS_INVALID_PARAMETERS);
566 		else if (res == WMM_ADDTS_STATUS_REFUSED)
567 			rdie->status_code =
568 				host_to_le16(WLAN_STATUS_REQUEST_DECLINED);
569 		else {
570 			/* TSPEC accepted; include updated TSPEC in response */
571 			rdie->descr_count = 1;
572 			pos += sizeof(*tspec);
573 		}
574 		return pos;
575 	}
576 #endif /* NEED_AP_MLME */
577 
578 	if (parse.wmm_tspec && !sm->wpa_auth->conf.ap_mlme) {
579 		struct wmm_tspec_element *tspec;
580 		int res;
581 
582 		tspec = (struct wmm_tspec_element *) pos;
583 		os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec));
584 		res = wpa_ft_add_tspec(sm->wpa_auth, sm->addr, pos,
585 				       sizeof(*tspec));
586 		if (res >= 0) {
587 			if (res)
588 				rdie->status_code = host_to_le16(res);
589 			else {
590 				/* TSPEC accepted; include updated TSPEC in
591 				 * response */
592 				rdie->descr_count = 1;
593 				pos += sizeof(*tspec);
594 			}
595 			return pos;
596 		}
597 	}
598 
599 	wpa_printf(MSG_DEBUG, "FT: No supported resource requested");
600 	rdie->status_code = host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
601 	return pos;
602 }
603 
604 
wpa_ft_process_ric(struct wpa_state_machine * sm,u8 * pos,u8 * end,const u8 * ric,size_t ric_len)605 static u8 * wpa_ft_process_ric(struct wpa_state_machine *sm, u8 *pos, u8 *end,
606 			       const u8 *ric, size_t ric_len)
607 {
608 	const u8 *rpos, *start;
609 	const struct rsn_rdie *rdie;
610 
611 	wpa_hexdump(MSG_MSGDUMP, "FT: RIC Request", ric, ric_len);
612 
613 	rpos = ric;
614 	while (rpos + sizeof(*rdie) < ric + ric_len) {
615 		if (rpos[0] != WLAN_EID_RIC_DATA || rpos[1] < sizeof(*rdie) ||
616 		    rpos + 2 + rpos[1] > ric + ric_len)
617 			break;
618 		rdie = (const struct rsn_rdie *) (rpos + 2);
619 		rpos += 2 + rpos[1];
620 		start = rpos;
621 
622 		while (rpos + 2 <= ric + ric_len &&
623 		       rpos + 2 + rpos[1] <= ric + ric_len) {
624 			if (rpos[0] == WLAN_EID_RIC_DATA)
625 				break;
626 			rpos += 2 + rpos[1];
627 		}
628 		pos = wpa_ft_process_rdie(sm, pos, end, rdie->id,
629 					  rdie->descr_count,
630 					  start, rpos - start);
631 	}
632 
633 	return pos;
634 }
635 
636 
wpa_sm_write_assoc_resp_ies(struct wpa_state_machine * sm,u8 * pos,size_t max_len,int auth_alg,const u8 * req_ies,size_t req_ies_len)637 u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
638 				 size_t max_len, int auth_alg,
639 				 const u8 *req_ies, size_t req_ies_len)
640 {
641 	u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
642 	size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
643 	int res;
644 	struct wpa_auth_config *conf;
645 	struct rsn_ftie *_ftie;
646 	struct wpa_ft_ies parse;
647 	u8 *ric_start;
648 	u8 *anonce, *snonce;
649 
650 	if (sm == NULL)
651 		return pos;
652 
653 	conf = &sm->wpa_auth->conf;
654 
655 	if (!wpa_key_mgmt_ft(sm->wpa_key_mgmt))
656 		return pos;
657 
658 	end = pos + max_len;
659 
660 	if (auth_alg == WLAN_AUTH_FT) {
661 		/*
662 		 * RSN (only present if this is a Reassociation Response and
663 		 * part of a fast BSS transition)
664 		 */
665 		res = wpa_write_rsn_ie(conf, pos, end - pos, sm->pmk_r1_name);
666 		if (res < 0)
667 			return pos;
668 		rsnie = pos;
669 		rsnie_len = res;
670 		pos += res;
671 	}
672 
673 	/* Mobility Domain Information */
674 	res = wpa_write_mdie(conf, pos, end - pos);
675 	if (res < 0)
676 		return pos;
677 	mdie = pos;
678 	mdie_len = res;
679 	pos += res;
680 
681 	/* Fast BSS Transition Information */
682 	if (auth_alg == WLAN_AUTH_FT) {
683 		subelem = wpa_ft_gtk_subelem(sm, &subelem_len);
684 		r0kh_id = sm->r0kh_id;
685 		r0kh_id_len = sm->r0kh_id_len;
686 		anonce = sm->ANonce;
687 		snonce = sm->SNonce;
688 #ifdef CONFIG_IEEE80211W
689 		if (sm->mgmt_frame_prot) {
690 			u8 *igtk;
691 			size_t igtk_len;
692 			u8 *nbuf;
693 			igtk = wpa_ft_igtk_subelem(sm, &igtk_len);
694 			if (igtk == NULL) {
695 				os_free(subelem);
696 				return pos;
697 			}
698 			nbuf = os_realloc(subelem, subelem_len + igtk_len);
699 			if (nbuf == NULL) {
700 				os_free(subelem);
701 				os_free(igtk);
702 				return pos;
703 			}
704 			subelem = nbuf;
705 			os_memcpy(subelem + subelem_len, igtk, igtk_len);
706 			subelem_len += igtk_len;
707 			os_free(igtk);
708 		}
709 #endif /* CONFIG_IEEE80211W */
710 	} else {
711 		r0kh_id = conf->r0_key_holder;
712 		r0kh_id_len = conf->r0_key_holder_len;
713 		anonce = NULL;
714 		snonce = NULL;
715 	}
716 	res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos,
717 			     end - pos, subelem, subelem_len);
718 	os_free(subelem);
719 	if (res < 0)
720 		return pos;
721 	ftie = pos;
722 	ftie_len = res;
723 	pos += res;
724 
725 	os_free(sm->assoc_resp_ftie);
726 	sm->assoc_resp_ftie = os_malloc(ftie_len);
727 	if (sm->assoc_resp_ftie)
728 		os_memcpy(sm->assoc_resp_ftie, ftie, ftie_len);
729 
730 	_ftie = (struct rsn_ftie *) (ftie + 2);
731 	if (auth_alg == WLAN_AUTH_FT)
732 		_ftie->mic_control[1] = 3; /* Information element count */
733 
734 	ric_start = pos;
735 	if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse) == 0 && parse.ric) {
736 		pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
737 					 parse.ric_len);
738 		if (auth_alg == WLAN_AUTH_FT)
739 			_ftie->mic_control[1] +=
740 				ieee802_11_ie_count(ric_start,
741 						    pos - ric_start);
742 	}
743 	if (ric_start == pos)
744 		ric_start = NULL;
745 
746 	if (auth_alg == WLAN_AUTH_FT &&
747 	    wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 6,
748 		       mdie, mdie_len, ftie, ftie_len,
749 		       rsnie, rsnie_len,
750 		       ric_start, ric_start ? pos - ric_start : 0,
751 		       _ftie->mic) < 0)
752 		wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
753 
754 	return pos;
755 }
756 
757 
wpa_auth_set_key(struct wpa_authenticator * wpa_auth,int vlan_id,enum wpa_alg alg,const u8 * addr,int idx,u8 * key,size_t key_len)758 static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
759 				   int vlan_id,
760 				   enum wpa_alg alg, const u8 *addr, int idx,
761 				   u8 *key, size_t key_len)
762 {
763 	if (wpa_auth->cb.set_key == NULL)
764 		return -1;
765 	return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
766 				    key, key_len);
767 }
768 
769 
wpa_ft_install_ptk(struct wpa_state_machine * sm)770 void wpa_ft_install_ptk(struct wpa_state_machine *sm)
771 {
772 	enum wpa_alg alg;
773 	int klen;
774 
775 	/* MLME-SETKEYS.request(PTK) */
776 	alg = wpa_cipher_to_alg(sm->pairwise);
777 	klen = wpa_cipher_key_len(sm->pairwise);
778 	if (!wpa_cipher_valid_pairwise(sm->pairwise)) {
779 		wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip "
780 			   "PTK configuration", sm->pairwise);
781 		return;
782 	}
783 
784 	/* FIX: add STA entry to kernel/driver here? The set_key will fail
785 	 * most likely without this.. At the moment, STA entry is added only
786 	 * after association has been completed. This function will be called
787 	 * again after association to get the PTK configured, but that could be
788 	 * optimized by adding the STA entry earlier.
789 	 */
790 	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
791 			     sm->PTK.tk1, klen))
792 		return;
793 
794 	/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
795 	sm->pairwise_set = TRUE;
796 }
797 
798 
wpa_ft_process_auth_req(struct wpa_state_machine * sm,const u8 * ies,size_t ies_len,u8 ** resp_ies,size_t * resp_ies_len)799 static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
800 				   const u8 *ies, size_t ies_len,
801 				   u8 **resp_ies, size_t *resp_ies_len)
802 {
803 	struct rsn_mdie *mdie;
804 	struct rsn_ftie *ftie;
805 	u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
806 	u8 ptk_name[WPA_PMK_NAME_LEN];
807 	struct wpa_auth_config *conf;
808 	struct wpa_ft_ies parse;
809 	size_t buflen, ptk_len;
810 	int ret;
811 	u8 *pos, *end;
812 	int pairwise;
813 
814 	*resp_ies = NULL;
815 	*resp_ies_len = 0;
816 
817 	sm->pmk_r1_name_valid = 0;
818 	conf = &sm->wpa_auth->conf;
819 
820 	wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
821 		    ies, ies_len);
822 
823 	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
824 		wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
825 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
826 	}
827 
828 	mdie = (struct rsn_mdie *) parse.mdie;
829 	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
830 	    os_memcmp(mdie->mobility_domain,
831 		      sm->wpa_auth->conf.mobility_domain,
832 		      MOBILITY_DOMAIN_ID_LEN) != 0) {
833 		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
834 		return WLAN_STATUS_INVALID_MDIE;
835 	}
836 
837 	ftie = (struct rsn_ftie *) parse.ftie;
838 	if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
839 		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
840 		return WLAN_STATUS_INVALID_FTIE;
841 	}
842 
843 	os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
844 
845 	if (parse.r0kh_id == NULL) {
846 		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
847 		return WLAN_STATUS_INVALID_FTIE;
848 	}
849 
850 	wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID",
851 		    parse.r0kh_id, parse.r0kh_id_len);
852 	os_memcpy(sm->r0kh_id, parse.r0kh_id, parse.r0kh_id_len);
853 	sm->r0kh_id_len = parse.r0kh_id_len;
854 
855 	if (parse.rsn_pmkid == NULL) {
856 		wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
857 		return WLAN_STATUS_INVALID_PMKID;
858 	}
859 
860 	wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name",
861 		    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
862 	wpa_derive_pmk_r1_name(parse.rsn_pmkid,
863 			       sm->wpa_auth->conf.r1_key_holder, sm->addr,
864 			       pmk_r1_name);
865 	wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
866 		    pmk_r1_name, WPA_PMK_NAME_LEN);
867 
868 	if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, pmk_r1,
869 		    &pairwise) < 0) {
870 		if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) {
871 			wpa_printf(MSG_DEBUG, "FT: Did not have matching "
872 				   "PMK-R1 and unknown R0KH-ID");
873 			return WLAN_STATUS_INVALID_PMKID;
874 		}
875 
876 		return -1; /* Status pending */
877 	}
878 
879 	wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN);
880 	sm->pmk_r1_name_valid = 1;
881 	os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
882 
883 	if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
884 		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
885 			   "ANonce");
886 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
887 	}
888 
889 	wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
890 		    sm->SNonce, WPA_NONCE_LEN);
891 	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
892 		    sm->ANonce, WPA_NONCE_LEN);
893 
894 	ptk_len = pairwise == WPA_CIPHER_TKIP ? 64 : 48;
895 	wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
896 			  sm->wpa_auth->addr, pmk_r1_name,
897 			  (u8 *) &sm->PTK, ptk_len, ptk_name);
898 	wpa_hexdump_key(MSG_DEBUG, "FT: PTK",
899 			(u8 *) &sm->PTK, ptk_len);
900 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
901 
902 	sm->pairwise = pairwise;
903 	sm->PTK_valid = TRUE;
904 	wpa_ft_install_ptk(sm);
905 
906 	buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
907 		2 + FT_R1KH_ID_LEN + 200;
908 	*resp_ies = os_zalloc(buflen);
909 	if (*resp_ies == NULL) {
910 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
911 	}
912 
913 	pos = *resp_ies;
914 	end = *resp_ies + buflen;
915 
916 	ret = wpa_write_rsn_ie(conf, pos, end - pos, parse.rsn_pmkid);
917 	if (ret < 0) {
918 		os_free(*resp_ies);
919 		*resp_ies = NULL;
920 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
921 	}
922 	pos += ret;
923 
924 	ret = wpa_write_mdie(conf, pos, end - pos);
925 	if (ret < 0) {
926 		os_free(*resp_ies);
927 		*resp_ies = NULL;
928 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
929 	}
930 	pos += ret;
931 
932 	ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len,
933 			     sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
934 	if (ret < 0) {
935 		os_free(*resp_ies);
936 		*resp_ies = NULL;
937 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
938 	}
939 	pos += ret;
940 
941 	*resp_ies_len = pos - *resp_ies;
942 
943 	return WLAN_STATUS_SUCCESS;
944 }
945 
946 
wpa_ft_process_auth(struct wpa_state_machine * sm,const u8 * bssid,u16 auth_transaction,const u8 * ies,size_t ies_len,void (* cb)(void * ctx,const u8 * dst,const u8 * bssid,u16 auth_transaction,u16 status,const u8 * ies,size_t ies_len),void * ctx)947 void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
948 			 u16 auth_transaction, const u8 *ies, size_t ies_len,
949 			 void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
950 				    u16 auth_transaction, u16 status,
951 				    const u8 *ies, size_t ies_len),
952 			 void *ctx)
953 {
954 	u16 status;
955 	u8 *resp_ies;
956 	size_t resp_ies_len;
957 	int res;
958 
959 	if (sm == NULL) {
960 		wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but "
961 			   "WPA SM not available");
962 		return;
963 	}
964 
965 	wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
966 		   " BSSID=" MACSTR " transaction=%d",
967 		   MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
968 	sm->ft_pending_cb = cb;
969 	sm->ft_pending_cb_ctx = ctx;
970 	sm->ft_pending_auth_transaction = auth_transaction;
971 	res = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
972 				      &resp_ies_len);
973 	if (res < 0) {
974 		wpa_printf(MSG_DEBUG, "FT: Callback postponed until response is available");
975 		return;
976 	}
977 	status = res;
978 
979 	wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR
980 		   " auth_transaction=%d status=%d",
981 		   MAC2STR(sm->addr), auth_transaction + 1, status);
982 	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
983 	cb(ctx, sm->addr, bssid, auth_transaction + 1, status,
984 	   resp_ies, resp_ies_len);
985 	os_free(resp_ies);
986 }
987 
988 
wpa_ft_validate_reassoc(struct wpa_state_machine * sm,const u8 * ies,size_t ies_len)989 u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
990 			    size_t ies_len)
991 {
992 	struct wpa_ft_ies parse;
993 	struct rsn_mdie *mdie;
994 	struct rsn_ftie *ftie;
995 	u8 mic[16];
996 	unsigned int count;
997 
998 	if (sm == NULL)
999 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1000 
1001 	wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
1002 
1003 	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
1004 		wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
1005 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1006 	}
1007 
1008 	if (parse.rsn == NULL) {
1009 		wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req");
1010 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1011 	}
1012 
1013 	if (parse.rsn_pmkid == NULL) {
1014 		wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
1015 		return WLAN_STATUS_INVALID_PMKID;
1016 	}
1017 
1018 	if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)
1019 	    != 0) {
1020 		wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match "
1021 			   "with the PMKR1Name derived from auth request");
1022 		return WLAN_STATUS_INVALID_PMKID;
1023 	}
1024 
1025 	mdie = (struct rsn_mdie *) parse.mdie;
1026 	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
1027 	    os_memcmp(mdie->mobility_domain,
1028 		      sm->wpa_auth->conf.mobility_domain,
1029 		      MOBILITY_DOMAIN_ID_LEN) != 0) {
1030 		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
1031 		return WLAN_STATUS_INVALID_MDIE;
1032 	}
1033 
1034 	ftie = (struct rsn_ftie *) parse.ftie;
1035 	if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
1036 		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
1037 		return WLAN_STATUS_INVALID_FTIE;
1038 	}
1039 
1040 	if (os_memcmp(ftie->snonce, sm->SNonce, WPA_NONCE_LEN) != 0) {
1041 		wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
1042 		wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
1043 			    ftie->snonce, WPA_NONCE_LEN);
1044 		wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
1045 			    sm->SNonce, WPA_NONCE_LEN);
1046 		return -1;
1047 	}
1048 
1049 	if (os_memcmp(ftie->anonce, sm->ANonce, WPA_NONCE_LEN) != 0) {
1050 		wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
1051 		wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
1052 			    ftie->anonce, WPA_NONCE_LEN);
1053 		wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
1054 			    sm->ANonce, WPA_NONCE_LEN);
1055 		return -1;
1056 	}
1057 
1058 
1059 	if (parse.r0kh_id == NULL) {
1060 		wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE");
1061 		return -1;
1062 	}
1063 
1064 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
1065 	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
1066 	{
1067 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
1068 			   "the current R0KH-ID");
1069 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
1070 			    parse.r0kh_id, parse.r0kh_id_len);
1071 		wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
1072 			    sm->r0kh_id, sm->r0kh_id_len);
1073 		return -1;
1074 	}
1075 
1076 	if (parse.r1kh_id == NULL) {
1077 		wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE");
1078 		return -1;
1079 	}
1080 
1081 	if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
1082 			    FT_R1KH_ID_LEN) != 0) {
1083 		wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
1084 			   "ReassocReq");
1085 		wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE",
1086 			    parse.r1kh_id, FT_R1KH_ID_LEN);
1087 		wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID",
1088 			    sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
1089 		return -1;
1090 	}
1091 
1092 	if (parse.rsn_pmkid == NULL ||
1093 	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
1094 	{
1095 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
1096 			   "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
1097 		return -1;
1098 	}
1099 
1100 	count = 3;
1101 	if (parse.ric)
1102 		count += ieee802_11_ie_count(parse.ric, parse.ric_len);
1103 	if (ftie->mic_control[1] != count) {
1104 		wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
1105 			   "Control: received %u expected %u",
1106 			   ftie->mic_control[1], count);
1107 		return -1;
1108 	}
1109 
1110 	if (wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 5,
1111 		       parse.mdie - 2, parse.mdie_len + 2,
1112 		       parse.ftie - 2, parse.ftie_len + 2,
1113 		       parse.rsn - 2, parse.rsn_len + 2,
1114 		       parse.ric, parse.ric_len,
1115 		       mic) < 0) {
1116 		wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
1117 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1118 	}
1119 
1120 	if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
1121 		wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
1122 		wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
1123 			   MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
1124 		wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
1125 		wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
1126 		wpa_hexdump(MSG_MSGDUMP, "FT: MDIE",
1127 			    parse.mdie - 2, parse.mdie_len + 2);
1128 		wpa_hexdump(MSG_MSGDUMP, "FT: FTIE",
1129 			    parse.ftie - 2, parse.ftie_len + 2);
1130 		wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
1131 			    parse.rsn - 2, parse.rsn_len + 2);
1132 		return WLAN_STATUS_INVALID_FTIE;
1133 	}
1134 
1135 	return WLAN_STATUS_SUCCESS;
1136 }
1137 
1138 
wpa_ft_action_rx(struct wpa_state_machine * sm,const u8 * data,size_t len)1139 int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
1140 {
1141 	const u8 *sta_addr, *target_ap;
1142 	const u8 *ies;
1143 	size_t ies_len;
1144 	u8 action;
1145 	struct ft_rrb_frame *frame;
1146 
1147 	if (sm == NULL)
1148 		return -1;
1149 
1150 	/*
1151 	 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
1152 	 * FT Request action frame body[variable]
1153 	 */
1154 
1155 	if (len < 14) {
1156 		wpa_printf(MSG_DEBUG, "FT: Too short FT Action frame "
1157 			   "(len=%lu)", (unsigned long) len);
1158 		return -1;
1159 	}
1160 
1161 	action = data[1];
1162 	sta_addr = data + 2;
1163 	target_ap = data + 8;
1164 	ies = data + 14;
1165 	ies_len = len - 14;
1166 
1167 	wpa_printf(MSG_DEBUG, "FT: Received FT Action frame (STA=" MACSTR
1168 		   " Target AP=" MACSTR " Action=%d)",
1169 		   MAC2STR(sta_addr), MAC2STR(target_ap), action);
1170 
1171 	if (os_memcmp(sta_addr, sm->addr, ETH_ALEN) != 0) {
1172 		wpa_printf(MSG_DEBUG, "FT: Mismatch in FT Action STA address: "
1173 			   "STA=" MACSTR " STA-Address=" MACSTR,
1174 			   MAC2STR(sm->addr), MAC2STR(sta_addr));
1175 		return -1;
1176 	}
1177 
1178 	/*
1179 	 * Do some sanity checking on the target AP address (not own and not
1180 	 * broadcast. This could be extended to filter based on a list of known
1181 	 * APs in the MD (if such a list were configured).
1182 	 */
1183 	if ((target_ap[0] & 0x01) ||
1184 	    os_memcmp(target_ap, sm->wpa_auth->addr, ETH_ALEN) == 0) {
1185 		wpa_printf(MSG_DEBUG, "FT: Invalid Target AP in FT Action "
1186 			   "frame");
1187 		return -1;
1188 	}
1189 
1190 	wpa_hexdump(MSG_MSGDUMP, "FT: Action frame body", ies, ies_len);
1191 
1192 	/* RRB - Forward action frame to the target AP */
1193 	frame = os_malloc(sizeof(*frame) + len);
1194 	if (frame == NULL)
1195 		return -1;
1196 	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1197 	frame->packet_type = FT_PACKET_REQUEST;
1198 	frame->action_length = host_to_le16(len);
1199 	os_memcpy(frame->ap_address, sm->wpa_auth->addr, ETH_ALEN);
1200 	os_memcpy(frame + 1, data, len);
1201 
1202 	wpa_ft_rrb_send(sm->wpa_auth, target_ap, (u8 *) frame,
1203 			sizeof(*frame) + len);
1204 	os_free(frame);
1205 
1206 	return 0;
1207 }
1208 
1209 
wpa_ft_rrb_rx_request_cb(void * ctx,const u8 * dst,const u8 * bssid,u16 auth_transaction,u16 resp,const u8 * ies,size_t ies_len)1210 static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid,
1211 				     u16 auth_transaction, u16 resp,
1212 				     const u8 *ies, size_t ies_len)
1213 {
1214 	struct wpa_state_machine *sm = ctx;
1215 	wpa_printf(MSG_DEBUG, "FT: Over-the-DS RX request cb for " MACSTR,
1216 		   MAC2STR(sm->addr));
1217 	wpa_ft_send_rrb_auth_resp(sm, sm->ft_pending_current_ap, sm->addr,
1218 				  WLAN_STATUS_SUCCESS, ies, ies_len);
1219 }
1220 
1221 
wpa_ft_rrb_rx_request(struct wpa_authenticator * wpa_auth,const u8 * current_ap,const u8 * sta_addr,const u8 * body,size_t len)1222 static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
1223 				 const u8 *current_ap, const u8 *sta_addr,
1224 				 const u8 *body, size_t len)
1225 {
1226 	struct wpa_state_machine *sm;
1227 	u16 status;
1228 	u8 *resp_ies;
1229 	size_t resp_ies_len;
1230 	int res;
1231 
1232 	sm = wpa_ft_add_sta(wpa_auth, sta_addr);
1233 	if (sm == NULL) {
1234 		wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
1235 			   "RRB Request");
1236 		return -1;
1237 	}
1238 
1239 	wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);
1240 
1241 	sm->ft_pending_cb = wpa_ft_rrb_rx_request_cb;
1242 	sm->ft_pending_cb_ctx = sm;
1243 	os_memcpy(sm->ft_pending_current_ap, current_ap, ETH_ALEN);
1244 	res = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
1245 				      &resp_ies_len);
1246 	if (res < 0) {
1247 		wpa_printf(MSG_DEBUG, "FT: No immediate response available - wait for pull response");
1248 		return 0;
1249 	}
1250 	status = res;
1251 
1252 	res = wpa_ft_send_rrb_auth_resp(sm, current_ap, sta_addr, status,
1253 					resp_ies, resp_ies_len);
1254 	os_free(resp_ies);
1255 	return res;
1256 }
1257 
1258 
wpa_ft_send_rrb_auth_resp(struct wpa_state_machine * sm,const u8 * current_ap,const u8 * sta_addr,u16 status,const u8 * resp_ies,size_t resp_ies_len)1259 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
1260 				     const u8 *current_ap, const u8 *sta_addr,
1261 				     u16 status, const u8 *resp_ies,
1262 				     size_t resp_ies_len)
1263 {
1264 	struct wpa_authenticator *wpa_auth = sm->wpa_auth;
1265 	size_t rlen;
1266 	struct ft_rrb_frame *frame;
1267 	u8 *pos;
1268 
1269 	wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
1270 		   " CurrentAP=" MACSTR " status=%d",
1271 		   MAC2STR(sm->addr), MAC2STR(current_ap), status);
1272 	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
1273 
1274 	/* RRB - Forward action frame response to the Current AP */
1275 
1276 	/*
1277 	 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
1278 	 * Status_Code[2] FT Request action frame body[variable]
1279 	 */
1280 	rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;
1281 
1282 	frame = os_malloc(sizeof(*frame) + rlen);
1283 	if (frame == NULL)
1284 		return -1;
1285 	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1286 	frame->packet_type = FT_PACKET_RESPONSE;
1287 	frame->action_length = host_to_le16(rlen);
1288 	os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN);
1289 	pos = (u8 *) (frame + 1);
1290 	*pos++ = WLAN_ACTION_FT;
1291 	*pos++ = 2; /* Action: Response */
1292 	os_memcpy(pos, sta_addr, ETH_ALEN);
1293 	pos += ETH_ALEN;
1294 	os_memcpy(pos, wpa_auth->addr, ETH_ALEN);
1295 	pos += ETH_ALEN;
1296 	WPA_PUT_LE16(pos, status);
1297 	pos += 2;
1298 	if (resp_ies)
1299 		os_memcpy(pos, resp_ies, resp_ies_len);
1300 
1301 	wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
1302 			sizeof(*frame) + rlen);
1303 	os_free(frame);
1304 
1305 	return 0;
1306 }
1307 
1308 
wpa_ft_rrb_rx_pull(struct wpa_authenticator * wpa_auth,const u8 * src_addr,const u8 * data,size_t data_len)1309 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
1310 			      const u8 *src_addr,
1311 			      const u8 *data, size_t data_len)
1312 {
1313 	struct ft_r0kh_r1kh_pull_frame *frame, f;
1314 	struct ft_remote_r1kh *r1kh;
1315 	struct ft_r0kh_r1kh_resp_frame resp, r;
1316 	u8 pmk_r0[PMK_LEN];
1317 	int pairwise;
1318 
1319 	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull");
1320 
1321 	if (data_len < sizeof(*frame))
1322 		return -1;
1323 
1324 	r1kh = wpa_auth->conf.r1kh_list;
1325 	while (r1kh) {
1326 		if (os_memcmp(r1kh->addr, src_addr, ETH_ALEN) == 0)
1327 			break;
1328 		r1kh = r1kh->next;
1329 	}
1330 	if (r1kh == NULL) {
1331 		wpa_printf(MSG_DEBUG, "FT: No matching R1KH address found for "
1332 			   "PMK-R1 pull source address " MACSTR,
1333 			   MAC2STR(src_addr));
1334 		return -1;
1335 	}
1336 
1337 	frame = (struct ft_r0kh_r1kh_pull_frame *) data;
1338 	/* aes_unwrap() does not support inplace decryption, so use a temporary
1339 	 * buffer for the data. */
1340 	if (aes_unwrap(r1kh->key, sizeof(r1kh->key),
1341 		       (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
1342 		       frame->nonce, f.nonce) < 0) {
1343 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
1344 			   "request from " MACSTR, MAC2STR(src_addr));
1345 		return -1;
1346 	}
1347 
1348 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
1349 		    f.nonce, sizeof(f.nonce));
1350 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name",
1351 		    f.pmk_r0_name, WPA_PMK_NAME_LEN);
1352 	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
1353 		   MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
1354 
1355 	os_memset(&resp, 0, sizeof(resp));
1356 	resp.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1357 	resp.packet_type = FT_PACKET_R0KH_R1KH_RESP;
1358 	resp.data_length = host_to_le16(FT_R0KH_R1KH_RESP_DATA_LEN);
1359 	os_memcpy(resp.ap_address, wpa_auth->addr, ETH_ALEN);
1360 
1361 	/* aes_wrap() does not support inplace encryption, so use a temporary
1362 	 * buffer for the data. */
1363 	os_memcpy(r.nonce, f.nonce, sizeof(f.nonce));
1364 	os_memcpy(r.r1kh_id, f.r1kh_id, FT_R1KH_ID_LEN);
1365 	os_memcpy(r.s1kh_id, f.s1kh_id, ETH_ALEN);
1366 	if (wpa_ft_fetch_pmk_r0(wpa_auth, f.s1kh_id, f.pmk_r0_name, pmk_r0,
1367 				&pairwise) < 0) {
1368 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name found for "
1369 			   "PMK-R1 pull");
1370 		return -1;
1371 	}
1372 
1373 	wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id,
1374 			  r.pmk_r1, r.pmk_r1_name);
1375 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN);
1376 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name,
1377 		    WPA_PMK_NAME_LEN);
1378 	r.pairwise = host_to_le16(pairwise);
1379 	os_memset(r.pad, 0, sizeof(r.pad));
1380 
1381 	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
1382 		     (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
1383 		     r.nonce, resp.nonce) < 0) {
1384 		os_memset(pmk_r0, 0, PMK_LEN);
1385 		return -1;
1386 	}
1387 
1388 	os_memset(pmk_r0, 0, PMK_LEN);
1389 
1390 	wpa_ft_rrb_send(wpa_auth, src_addr, (u8 *) &resp, sizeof(resp));
1391 
1392 	return 0;
1393 }
1394 
1395 
ft_pull_resp_cb_finish(void * eloop_ctx,void * timeout_ctx)1396 static void ft_pull_resp_cb_finish(void *eloop_ctx, void *timeout_ctx)
1397 {
1398 	struct wpa_state_machine *sm = eloop_ctx;
1399 	int res;
1400 	u8 *resp_ies;
1401 	size_t resp_ies_len;
1402 	u16 status;
1403 
1404 	res = wpa_ft_process_auth_req(sm, wpabuf_head(sm->ft_pending_req_ies),
1405 				      wpabuf_len(sm->ft_pending_req_ies),
1406 				      &resp_ies, &resp_ies_len);
1407 	wpabuf_free(sm->ft_pending_req_ies);
1408 	sm->ft_pending_req_ies = NULL;
1409 	if (res < 0)
1410 		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
1411 	status = res;
1412 	wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR
1413 		   " - status %u", MAC2STR(sm->addr), status);
1414 
1415 	sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr,
1416 			  sm->ft_pending_auth_transaction + 1, status,
1417 			  resp_ies, resp_ies_len);
1418 	os_free(resp_ies);
1419 }
1420 
1421 
ft_pull_resp_cb(struct wpa_state_machine * sm,void * ctx)1422 static int ft_pull_resp_cb(struct wpa_state_machine *sm, void *ctx)
1423 {
1424 	struct ft_r0kh_r1kh_resp_frame *frame = ctx;
1425 
1426 	if (os_memcmp(frame->s1kh_id, sm->addr, ETH_ALEN) != 0)
1427 		return 0;
1428 	if (os_memcmp(frame->nonce, sm->ft_pending_pull_nonce,
1429 		      FT_R0KH_R1KH_PULL_NONCE_LEN) != 0)
1430 		return 0;
1431 	if (sm->ft_pending_cb == NULL || sm->ft_pending_req_ies == NULL)
1432 		return 0;
1433 
1434 	wpa_printf(MSG_DEBUG, "FT: Response to a pending pull request for "
1435 		   MACSTR " - process from timeout", MAC2STR(sm->addr));
1436 	eloop_register_timeout(0, 0, ft_pull_resp_cb_finish, sm, NULL);
1437 	return 1;
1438 }
1439 
1440 
wpa_ft_rrb_rx_resp(struct wpa_authenticator * wpa_auth,const u8 * src_addr,const u8 * data,size_t data_len)1441 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
1442 			      const u8 *src_addr,
1443 			      const u8 *data, size_t data_len)
1444 {
1445 	struct ft_r0kh_r1kh_resp_frame *frame, f;
1446 	struct ft_remote_r0kh *r0kh;
1447 	int pairwise, res;
1448 
1449 	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response");
1450 
1451 	if (data_len < sizeof(*frame))
1452 		return -1;
1453 
1454 	r0kh = wpa_auth->conf.r0kh_list;
1455 	while (r0kh) {
1456 		if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
1457 			break;
1458 		r0kh = r0kh->next;
1459 	}
1460 	if (r0kh == NULL) {
1461 		wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
1462 			   "PMK-R0 pull response source address " MACSTR,
1463 			   MAC2STR(src_addr));
1464 		return -1;
1465 	}
1466 
1467 	frame = (struct ft_r0kh_r1kh_resp_frame *) data;
1468 	/* aes_unwrap() does not support inplace decryption, so use a temporary
1469 	 * buffer for the data. */
1470 	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
1471 		       (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
1472 		       frame->nonce, f.nonce) < 0) {
1473 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
1474 			   "response from " MACSTR, MAC2STR(src_addr));
1475 		return -1;
1476 	}
1477 
1478 	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
1479 			    FT_R1KH_ID_LEN) != 0) {
1480 		wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a "
1481 			   "matching R1KH-ID");
1482 		return -1;
1483 	}
1484 
1485 	pairwise = le_to_host16(f.pairwise);
1486 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
1487 		    f.nonce, sizeof(f.nonce));
1488 	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
1489 		   MACSTR " pairwise=0x%x",
1490 		   MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise);
1491 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 pull - PMK-R1",
1492 			f.pmk_r1, PMK_LEN);
1493 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR1Name",
1494 			f.pmk_r1_name, WPA_PMK_NAME_LEN);
1495 
1496 	res = wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
1497 				  pairwise);
1498 	wpa_printf(MSG_DEBUG, "FT: Look for pending pull request");
1499 	wpa_auth_for_each_sta(wpa_auth, ft_pull_resp_cb, &f);
1500 	os_memset(f.pmk_r1, 0, PMK_LEN);
1501 
1502 	return res ? 0 : -1;
1503 }
1504 
1505 
wpa_ft_rrb_rx_push(struct wpa_authenticator * wpa_auth,const u8 * src_addr,const u8 * data,size_t data_len)1506 static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth,
1507 			      const u8 *src_addr,
1508 			      const u8 *data, size_t data_len)
1509 {
1510 	struct ft_r0kh_r1kh_push_frame *frame, f;
1511 	struct ft_remote_r0kh *r0kh;
1512 	struct os_time now;
1513 	os_time_t tsend;
1514 	int pairwise;
1515 
1516 	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 push");
1517 
1518 	if (data_len < sizeof(*frame))
1519 		return -1;
1520 
1521 	r0kh = wpa_auth->conf.r0kh_list;
1522 	while (r0kh) {
1523 		if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
1524 			break;
1525 		r0kh = r0kh->next;
1526 	}
1527 	if (r0kh == NULL) {
1528 		wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
1529 			   "PMK-R0 push source address " MACSTR,
1530 			   MAC2STR(src_addr));
1531 		return -1;
1532 	}
1533 
1534 	frame = (struct ft_r0kh_r1kh_push_frame *) data;
1535 	/* aes_unwrap() does not support inplace decryption, so use a temporary
1536 	 * buffer for the data. */
1537 	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
1538 		       (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
1539 		       frame->timestamp, f.timestamp) < 0) {
1540 		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from "
1541 			   MACSTR, MAC2STR(src_addr));
1542 		return -1;
1543 	}
1544 
1545 	os_get_time(&now);
1546 	tsend = WPA_GET_LE32(f.timestamp);
1547 	if ((now.sec > tsend && now.sec - tsend > 60) ||
1548 	    (now.sec < tsend && tsend - now.sec > 60)) {
1549 		wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not have a valid "
1550 			   "timestamp: sender time %d own time %d\n",
1551 			   (int) tsend, (int) now.sec);
1552 		return -1;
1553 	}
1554 
1555 	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
1556 			    FT_R1KH_ID_LEN) != 0) {
1557 		wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching "
1558 			   "R1KH-ID (received " MACSTR " own " MACSTR ")",
1559 			   MAC2STR(f.r1kh_id),
1560 			   MAC2STR(wpa_auth->conf.r1_key_holder));
1561 		return -1;
1562 	}
1563 
1564 	pairwise = le_to_host16(f.pairwise);
1565 	wpa_printf(MSG_DEBUG, "FT: PMK-R1 push - R1KH-ID=" MACSTR " S1KH-ID="
1566 		   MACSTR " pairwise=0x%x",
1567 		   MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise);
1568 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 push - PMK-R1",
1569 			f.pmk_r1, PMK_LEN);
1570 	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 push - PMKR1Name",
1571 			f.pmk_r1_name, WPA_PMK_NAME_LEN);
1572 
1573 	wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
1574 			    pairwise);
1575 	os_memset(f.pmk_r1, 0, PMK_LEN);
1576 
1577 	return 0;
1578 }
1579 
1580 
wpa_ft_rrb_rx(struct wpa_authenticator * wpa_auth,const u8 * src_addr,const u8 * data,size_t data_len)1581 int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
1582 		  const u8 *data, size_t data_len)
1583 {
1584 	struct ft_rrb_frame *frame;
1585 	u16 alen;
1586 	const u8 *pos, *end, *start;
1587 	u8 action;
1588 	const u8 *sta_addr, *target_ap_addr;
1589 
1590 	wpa_printf(MSG_DEBUG, "FT: RRB received frame from remote AP " MACSTR,
1591 		   MAC2STR(src_addr));
1592 
1593 	if (data_len < sizeof(*frame)) {
1594 		wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (data_len=%lu)",
1595 			   (unsigned long) data_len);
1596 		return -1;
1597 	}
1598 
1599 	pos = data;
1600 	frame = (struct ft_rrb_frame *) pos;
1601 	pos += sizeof(*frame);
1602 
1603 	alen = le_to_host16(frame->action_length);
1604 	wpa_printf(MSG_DEBUG, "FT: RRB frame - frame_type=%d packet_type=%d "
1605 		   "action_length=%d ap_address=" MACSTR,
1606 		   frame->frame_type, frame->packet_type, alen,
1607 		   MAC2STR(frame->ap_address));
1608 
1609 	if (frame->frame_type != RSN_REMOTE_FRAME_TYPE_FT_RRB) {
1610 		/* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
1611 		wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with "
1612 			   "unrecognized type %d", frame->frame_type);
1613 		return -1;
1614 	}
1615 
1616 	if (alen > data_len - sizeof(*frame)) {
1617 		wpa_printf(MSG_DEBUG, "FT: RRB frame too short for action "
1618 			   "frame");
1619 		return -1;
1620 	}
1621 
1622 	if (frame->packet_type == FT_PACKET_R0KH_R1KH_PULL)
1623 		return wpa_ft_rrb_rx_pull(wpa_auth, src_addr, data, data_len);
1624 	if (frame->packet_type == FT_PACKET_R0KH_R1KH_RESP)
1625 		return wpa_ft_rrb_rx_resp(wpa_auth, src_addr, data, data_len);
1626 	if (frame->packet_type == FT_PACKET_R0KH_R1KH_PUSH)
1627 		return wpa_ft_rrb_rx_push(wpa_auth, src_addr, data, data_len);
1628 
1629 	wpa_hexdump(MSG_MSGDUMP, "FT: RRB - FT Action frame", pos, alen);
1630 
1631 	if (alen < 1 + 1 + 2 * ETH_ALEN) {
1632 		wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (not enough "
1633 			   "room for Action Frame body); alen=%lu",
1634 			   (unsigned long) alen);
1635 		return -1;
1636 	}
1637 	start = pos;
1638 	end = pos + alen;
1639 
1640 	if (*pos != WLAN_ACTION_FT) {
1641 		wpa_printf(MSG_DEBUG, "FT: Unexpected Action frame category "
1642 			   "%d", *pos);
1643 		return -1;
1644 	}
1645 
1646 	pos++;
1647 	action = *pos++;
1648 	sta_addr = pos;
1649 	pos += ETH_ALEN;
1650 	target_ap_addr = pos;
1651 	pos += ETH_ALEN;
1652 	wpa_printf(MSG_DEBUG, "FT: RRB Action Frame: action=%d sta_addr="
1653 		   MACSTR " target_ap_addr=" MACSTR,
1654 		   action, MAC2STR(sta_addr), MAC2STR(target_ap_addr));
1655 
1656 	if (frame->packet_type == FT_PACKET_REQUEST) {
1657 		wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Request");
1658 
1659 		if (action != 1) {
1660 			wpa_printf(MSG_DEBUG, "FT: Unexpected Action %d in "
1661 				   "RRB Request", action);
1662 			return -1;
1663 		}
1664 
1665 		if (os_memcmp(target_ap_addr, wpa_auth->addr, ETH_ALEN) != 0) {
1666 			wpa_printf(MSG_DEBUG, "FT: Target AP address in the "
1667 				   "RRB Request does not match with own "
1668 				   "address");
1669 			return -1;
1670 		}
1671 
1672 		if (wpa_ft_rrb_rx_request(wpa_auth, frame->ap_address,
1673 					  sta_addr, pos, end - pos) < 0)
1674 			return -1;
1675 	} else if (frame->packet_type == FT_PACKET_RESPONSE) {
1676 		u16 status_code;
1677 
1678 		if (end - pos < 2) {
1679 			wpa_printf(MSG_DEBUG, "FT: Not enough room for status "
1680 				   "code in RRB Response");
1681 			return -1;
1682 		}
1683 		status_code = WPA_GET_LE16(pos);
1684 		pos += 2;
1685 
1686 		wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response "
1687 			   "(status_code=%d)", status_code);
1688 
1689 		if (wpa_ft_action_send(wpa_auth, sta_addr, start, alen) < 0)
1690 			return -1;
1691 	} else {
1692 		wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with unknown "
1693 			   "packet_type %d", frame->packet_type);
1694 		return -1;
1695 	}
1696 
1697 	if (end > pos) {
1698 		wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end",
1699 			    pos, end - pos);
1700 	}
1701 
1702 	return 0;
1703 }
1704 
1705 
wpa_ft_generate_pmk_r1(struct wpa_authenticator * wpa_auth,struct wpa_ft_pmk_r0_sa * pmk_r0,struct ft_remote_r1kh * r1kh,const u8 * s1kh_id,int pairwise)1706 static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
1707 				   struct wpa_ft_pmk_r0_sa *pmk_r0,
1708 				   struct ft_remote_r1kh *r1kh,
1709 				   const u8 *s1kh_id, int pairwise)
1710 {
1711 	struct ft_r0kh_r1kh_push_frame frame, f;
1712 	struct os_time now;
1713 
1714 	os_memset(&frame, 0, sizeof(frame));
1715 	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1716 	frame.packet_type = FT_PACKET_R0KH_R1KH_PUSH;
1717 	frame.data_length = host_to_le16(FT_R0KH_R1KH_PUSH_DATA_LEN);
1718 	os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);
1719 
1720 	/* aes_wrap() does not support inplace encryption, so use a temporary
1721 	 * buffer for the data. */
1722 	os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN);
1723 	os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
1724 	os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN);
1725 	wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
1726 			  s1kh_id, f.pmk_r1, f.pmk_r1_name);
1727 	wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id));
1728 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN);
1729 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name,
1730 		    WPA_PMK_NAME_LEN);
1731 	os_get_time(&now);
1732 	WPA_PUT_LE32(f.timestamp, now.sec);
1733 	f.pairwise = host_to_le16(pairwise);
1734 	os_memset(f.pad, 0, sizeof(f.pad));
1735 	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
1736 		     (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
1737 		     f.timestamp, frame.timestamp) < 0)
1738 		return;
1739 
1740 	wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame));
1741 }
1742 
1743 
wpa_ft_push_pmk_r1(struct wpa_authenticator * wpa_auth,const u8 * addr)1744 void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr)
1745 {
1746 	struct wpa_ft_pmk_r0_sa *r0;
1747 	struct ft_remote_r1kh *r1kh;
1748 
1749 	if (!wpa_auth->conf.pmk_r1_push)
1750 		return;
1751 
1752 	r0 = wpa_auth->ft_pmk_cache->pmk_r0;
1753 	while (r0) {
1754 		if (os_memcmp(r0->spa, addr, ETH_ALEN) == 0)
1755 			break;
1756 		r0 = r0->next;
1757 	}
1758 
1759 	if (r0 == NULL || r0->pmk_r1_pushed)
1760 		return;
1761 	r0->pmk_r1_pushed = 1;
1762 
1763 	wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
1764 		   "for STA " MACSTR, MAC2STR(addr));
1765 
1766 	r1kh = wpa_auth->conf.r1kh_list;
1767 	while (r1kh) {
1768 		wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr, r0->pairwise);
1769 		r1kh = r1kh->next;
1770 	}
1771 }
1772 
1773 #endif /* CONFIG_IEEE80211R */
1774