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