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	/* FIX: add STA entry to kernel/driver here? The set_key will fail
801	 * most likely without this.. At the moment, STA entry is added only
802	 * after association has been completed. This function will be called
803	 * again after association to get the PTK configured, but that could be
804	 * optimized by adding the STA entry earlier.
805	 */
806	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
807			     sm->PTK.tk, klen))
808		return;
809
810	/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
811	sm->pairwise_set = TRUE;
812}
813
814
815/* Derive PMK-R1 from PSK, check all available PSK */
816static int wpa_ft_psk_pmk_r1(struct wpa_state_machine *sm,
817			     const u8 *req_pmk_r1_name,
818			     u8 *out_pmk_r1, int *out_pairwise)
819{
820	const u8 *pmk = NULL;
821	u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
822	u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
823	struct wpa_authenticator *wpa_auth = sm->wpa_auth;
824	const u8 *mdid = wpa_auth->conf.mobility_domain;
825	const u8 *r0kh = sm->r0kh_id;
826	size_t r0kh_len = sm->r0kh_id_len;
827	const u8 *r1kh = wpa_auth->conf.r1_key_holder;
828	const u8 *ssid = wpa_auth->conf.ssid;
829	size_t ssid_len = wpa_auth->conf.ssid_len;
830	int pairwise;
831
832	pairwise = sm->pairwise;
833
834	for (;;) {
835		pmk = wpa_ft_get_psk(wpa_auth, sm->addr, sm->p2p_dev_addr,
836				     pmk);
837		if (pmk == NULL)
838			break;
839
840		if (wpa_derive_pmk_r0(pmk, PMK_LEN, ssid, ssid_len, mdid, r0kh,
841				      r0kh_len, sm->addr,
842				      pmk_r0, pmk_r0_name) < 0 ||
843		    wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
844				      pmk_r1, pmk_r1_name) < 0 ||
845		    os_memcmp_const(pmk_r1_name, req_pmk_r1_name,
846				    WPA_PMK_NAME_LEN) != 0)
847			continue;
848
849		/* We found a PSK that matches the requested pmk_r1_name */
850		wpa_printf(MSG_DEBUG,
851			   "FT: Found PSK to generate PMK-R1 locally");
852		os_memcpy(out_pmk_r1, pmk_r1, PMK_LEN);
853		if (out_pairwise)
854			*out_pairwise = pairwise;
855		return 0;
856	}
857
858	wpa_printf(MSG_DEBUG,
859		   "FT: Did not find PSK to generate PMK-R1 locally");
860	return -1;
861}
862
863
864/* Detect the configuration the station asked for.
865 * Required to detect FT-PSK and pairwise cipher.
866 */
867static int wpa_ft_set_key_mgmt(struct wpa_state_machine *sm,
868			       struct wpa_ft_ies *parse)
869{
870	int key_mgmt, ciphers;
871
872	if (sm->wpa_key_mgmt)
873		return 0;
874
875	key_mgmt = parse->key_mgmt & sm->wpa_auth->conf.wpa_key_mgmt;
876	if (!key_mgmt) {
877		wpa_printf(MSG_DEBUG, "FT: Invalid key mgmt (0x%x) from "
878			   MACSTR, parse->key_mgmt, MAC2STR(sm->addr));
879		return -1;
880	}
881	if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
882		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
883	else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
884		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
885	ciphers = parse->pairwise_cipher & sm->wpa_auth->conf.rsn_pairwise;
886	if (!ciphers) {
887		wpa_printf(MSG_DEBUG, "FT: Invalid pairwise cipher (0x%x) from "
888			   MACSTR,
889			   parse->pairwise_cipher, MAC2STR(sm->addr));
890		return -1;
891	}
892	sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
893
894	return 0;
895}
896
897
898static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
899				   const u8 *ies, size_t ies_len,
900				   u8 **resp_ies, size_t *resp_ies_len)
901{
902	struct rsn_mdie *mdie;
903	struct rsn_ftie *ftie;
904	u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
905	u8 ptk_name[WPA_PMK_NAME_LEN];
906	struct wpa_auth_config *conf;
907	struct wpa_ft_ies parse;
908	size_t buflen;
909	int ret;
910	u8 *pos, *end;
911	int pairwise;
912
913	*resp_ies = NULL;
914	*resp_ies_len = 0;
915
916	sm->pmk_r1_name_valid = 0;
917	conf = &sm->wpa_auth->conf;
918
919	wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
920		    ies, ies_len);
921
922	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
923		wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
924		return WLAN_STATUS_UNSPECIFIED_FAILURE;
925	}
926
927	mdie = (struct rsn_mdie *) parse.mdie;
928	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
929	    os_memcmp(mdie->mobility_domain,
930		      sm->wpa_auth->conf.mobility_domain,
931		      MOBILITY_DOMAIN_ID_LEN) != 0) {
932		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
933		return WLAN_STATUS_INVALID_MDIE;
934	}
935
936	ftie = (struct rsn_ftie *) parse.ftie;
937	if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
938		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
939		return WLAN_STATUS_INVALID_FTIE;
940	}
941
942	os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
943
944	if (parse.r0kh_id == NULL) {
945		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
946		return WLAN_STATUS_INVALID_FTIE;
947	}
948
949	wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID",
950		    parse.r0kh_id, parse.r0kh_id_len);
951	os_memcpy(sm->r0kh_id, parse.r0kh_id, parse.r0kh_id_len);
952	sm->r0kh_id_len = parse.r0kh_id_len;
953
954	if (parse.rsn_pmkid == NULL) {
955		wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
956		return WLAN_STATUS_INVALID_PMKID;
957	}
958
959	if (wpa_ft_set_key_mgmt(sm, &parse) < 0)
960		return WLAN_STATUS_UNSPECIFIED_FAILURE;
961
962	wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name",
963		    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
964	if (wpa_derive_pmk_r1_name(parse.rsn_pmkid,
965				   sm->wpa_auth->conf.r1_key_holder, sm->addr,
966				   pmk_r1_name) < 0)
967		return WLAN_STATUS_UNSPECIFIED_FAILURE;
968	wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
969		    pmk_r1_name, WPA_PMK_NAME_LEN);
970
971	if (conf->ft_psk_generate_local &&
972	    wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) {
973		if (wpa_ft_psk_pmk_r1(sm, pmk_r1_name, pmk_r1, &pairwise) < 0)
974			return WLAN_STATUS_INVALID_PMKID;
975	} else if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name,
976				       pmk_r1, &pairwise) < 0) {
977		if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) {
978			wpa_printf(MSG_DEBUG, "FT: Did not have matching "
979				   "PMK-R1 and unknown R0KH-ID");
980			return WLAN_STATUS_INVALID_PMKID;
981		}
982
983		return -1; /* Status pending */
984	}
985
986	wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN);
987	sm->pmk_r1_name_valid = 1;
988	os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
989
990	if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
991		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
992			   "ANonce");
993		return WLAN_STATUS_UNSPECIFIED_FAILURE;
994	}
995
996	wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
997		    sm->SNonce, WPA_NONCE_LEN);
998	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
999		    sm->ANonce, WPA_NONCE_LEN);
1000
1001	if (wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
1002			      sm->wpa_auth->addr, pmk_r1_name,
1003			      &sm->PTK, ptk_name, sm->wpa_key_mgmt,
1004			      pairwise) < 0)
1005		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1006
1007	sm->pairwise = pairwise;
1008	sm->PTK_valid = TRUE;
1009	wpa_ft_install_ptk(sm);
1010
1011	buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
1012		2 + FT_R1KH_ID_LEN + 200;
1013	*resp_ies = os_zalloc(buflen);
1014	if (*resp_ies == NULL)
1015		goto fail;
1016
1017	pos = *resp_ies;
1018	end = *resp_ies + buflen;
1019
1020	ret = wpa_write_rsn_ie(conf, pos, end - pos, parse.rsn_pmkid);
1021	if (ret < 0)
1022		goto fail;
1023	pos += ret;
1024
1025	ret = wpa_write_mdie(conf, pos, end - pos);
1026	if (ret < 0)
1027		goto fail;
1028	pos += ret;
1029
1030	ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len,
1031			     sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
1032	if (ret < 0)
1033		goto fail;
1034	pos += ret;
1035
1036	*resp_ies_len = pos - *resp_ies;
1037
1038	return WLAN_STATUS_SUCCESS;
1039fail:
1040	os_free(*resp_ies);
1041	*resp_ies = NULL;
1042	return WLAN_STATUS_UNSPECIFIED_FAILURE;
1043}
1044
1045
1046void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
1047			 u16 auth_transaction, const u8 *ies, size_t ies_len,
1048			 void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
1049				    u16 auth_transaction, u16 status,
1050				    const u8 *ies, size_t ies_len),
1051			 void *ctx)
1052{
1053	u16 status;
1054	u8 *resp_ies;
1055	size_t resp_ies_len;
1056	int res;
1057
1058	if (sm == NULL) {
1059		wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but "
1060			   "WPA SM not available");
1061		return;
1062	}
1063
1064	wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
1065		   " BSSID=" MACSTR " transaction=%d",
1066		   MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
1067	sm->ft_pending_cb = cb;
1068	sm->ft_pending_cb_ctx = ctx;
1069	sm->ft_pending_auth_transaction = auth_transaction;
1070	res = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
1071				      &resp_ies_len);
1072	if (res < 0) {
1073		wpa_printf(MSG_DEBUG, "FT: Callback postponed until response is available");
1074		return;
1075	}
1076	status = res;
1077
1078	wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR
1079		   " auth_transaction=%d status=%d",
1080		   MAC2STR(sm->addr), auth_transaction + 1, status);
1081	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
1082	cb(ctx, sm->addr, bssid, auth_transaction + 1, status,
1083	   resp_ies, resp_ies_len);
1084	os_free(resp_ies);
1085}
1086
1087
1088u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
1089			    size_t ies_len)
1090{
1091	struct wpa_ft_ies parse;
1092	struct rsn_mdie *mdie;
1093	struct rsn_ftie *ftie;
1094	u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
1095	size_t mic_len = 16;
1096	unsigned int count;
1097
1098	if (sm == NULL)
1099		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1100
1101	wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
1102
1103	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
1104		wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
1105		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1106	}
1107
1108	if (parse.rsn == NULL) {
1109		wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req");
1110		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1111	}
1112
1113	if (parse.rsn_pmkid == NULL) {
1114		wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
1115		return WLAN_STATUS_INVALID_PMKID;
1116	}
1117
1118	if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)
1119	    != 0) {
1120		wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match "
1121			   "with the PMKR1Name derived from auth request");
1122		return WLAN_STATUS_INVALID_PMKID;
1123	}
1124
1125	mdie = (struct rsn_mdie *) parse.mdie;
1126	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
1127	    os_memcmp(mdie->mobility_domain,
1128		      sm->wpa_auth->conf.mobility_domain,
1129		      MOBILITY_DOMAIN_ID_LEN) != 0) {
1130		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
1131		return WLAN_STATUS_INVALID_MDIE;
1132	}
1133
1134	ftie = (struct rsn_ftie *) parse.ftie;
1135	if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
1136		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
1137		return WLAN_STATUS_INVALID_FTIE;
1138	}
1139
1140	if (os_memcmp(ftie->snonce, sm->SNonce, WPA_NONCE_LEN) != 0) {
1141		wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
1142		wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
1143			    ftie->snonce, WPA_NONCE_LEN);
1144		wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
1145			    sm->SNonce, WPA_NONCE_LEN);
1146		return WLAN_STATUS_INVALID_FTIE;
1147	}
1148
1149	if (os_memcmp(ftie->anonce, sm->ANonce, WPA_NONCE_LEN) != 0) {
1150		wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
1151		wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
1152			    ftie->anonce, WPA_NONCE_LEN);
1153		wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
1154			    sm->ANonce, WPA_NONCE_LEN);
1155		return WLAN_STATUS_INVALID_FTIE;
1156	}
1157
1158
1159	if (parse.r0kh_id == NULL) {
1160		wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE");
1161		return WLAN_STATUS_INVALID_FTIE;
1162	}
1163
1164	if (parse.r0kh_id_len != sm->r0kh_id_len ||
1165	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
1166	{
1167		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
1168			   "the current R0KH-ID");
1169		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
1170			    parse.r0kh_id, parse.r0kh_id_len);
1171		wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
1172			    sm->r0kh_id, sm->r0kh_id_len);
1173		return WLAN_STATUS_INVALID_FTIE;
1174	}
1175
1176	if (parse.r1kh_id == NULL) {
1177		wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE");
1178		return WLAN_STATUS_INVALID_FTIE;
1179	}
1180
1181	if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
1182			    FT_R1KH_ID_LEN) != 0) {
1183		wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
1184			   "ReassocReq");
1185		wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE",
1186			    parse.r1kh_id, FT_R1KH_ID_LEN);
1187		wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID",
1188			    sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
1189		return WLAN_STATUS_INVALID_FTIE;
1190	}
1191
1192	if (parse.rsn_pmkid == NULL ||
1193	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
1194	{
1195		wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
1196			   "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
1197		return WLAN_STATUS_INVALID_PMKID;
1198	}
1199
1200	count = 3;
1201	if (parse.ric)
1202		count += ieee802_11_ie_count(parse.ric, parse.ric_len);
1203	if (ftie->mic_control[1] != count) {
1204		wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
1205			   "Control: received %u expected %u",
1206			   ftie->mic_control[1], count);
1207		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1208	}
1209
1210	if (wpa_ft_mic(sm->PTK.kck, sm->PTK.kck_len, sm->addr,
1211		       sm->wpa_auth->addr, 5,
1212		       parse.mdie - 2, parse.mdie_len + 2,
1213		       parse.ftie - 2, parse.ftie_len + 2,
1214		       parse.rsn - 2, parse.rsn_len + 2,
1215		       parse.ric, parse.ric_len,
1216		       mic) < 0) {
1217		wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
1218		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1219	}
1220
1221	if (os_memcmp_const(mic, ftie->mic, mic_len) != 0) {
1222		wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
1223		wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
1224			   MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
1225		wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
1226			    ftie->mic, mic_len);
1227		wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, mic_len);
1228		wpa_hexdump(MSG_MSGDUMP, "FT: MDIE",
1229			    parse.mdie - 2, parse.mdie_len + 2);
1230		wpa_hexdump(MSG_MSGDUMP, "FT: FTIE",
1231			    parse.ftie - 2, parse.ftie_len + 2);
1232		wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
1233			    parse.rsn - 2, parse.rsn_len + 2);
1234		return WLAN_STATUS_INVALID_FTIE;
1235	}
1236
1237	return WLAN_STATUS_SUCCESS;
1238}
1239
1240
1241int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
1242{
1243	const u8 *sta_addr, *target_ap;
1244	const u8 *ies;
1245	size_t ies_len;
1246	u8 action;
1247	struct ft_rrb_frame *frame;
1248
1249	if (sm == NULL)
1250		return -1;
1251
1252	/*
1253	 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
1254	 * FT Request action frame body[variable]
1255	 */
1256
1257	if (len < 14) {
1258		wpa_printf(MSG_DEBUG, "FT: Too short FT Action frame "
1259			   "(len=%lu)", (unsigned long) len);
1260		return -1;
1261	}
1262
1263	action = data[1];
1264	sta_addr = data + 2;
1265	target_ap = data + 8;
1266	ies = data + 14;
1267	ies_len = len - 14;
1268
1269	wpa_printf(MSG_DEBUG, "FT: Received FT Action frame (STA=" MACSTR
1270		   " Target AP=" MACSTR " Action=%d)",
1271		   MAC2STR(sta_addr), MAC2STR(target_ap), action);
1272
1273	if (os_memcmp(sta_addr, sm->addr, ETH_ALEN) != 0) {
1274		wpa_printf(MSG_DEBUG, "FT: Mismatch in FT Action STA address: "
1275			   "STA=" MACSTR " STA-Address=" MACSTR,
1276			   MAC2STR(sm->addr), MAC2STR(sta_addr));
1277		return -1;
1278	}
1279
1280	/*
1281	 * Do some sanity checking on the target AP address (not own and not
1282	 * broadcast. This could be extended to filter based on a list of known
1283	 * APs in the MD (if such a list were configured).
1284	 */
1285	if ((target_ap[0] & 0x01) ||
1286	    os_memcmp(target_ap, sm->wpa_auth->addr, ETH_ALEN) == 0) {
1287		wpa_printf(MSG_DEBUG, "FT: Invalid Target AP in FT Action "
1288			   "frame");
1289		return -1;
1290	}
1291
1292	wpa_hexdump(MSG_MSGDUMP, "FT: Action frame body", ies, ies_len);
1293
1294	if (!sm->wpa_auth->conf.ft_over_ds) {
1295		wpa_printf(MSG_DEBUG, "FT: Over-DS option disabled - reject");
1296		return -1;
1297	}
1298
1299	/* RRB - Forward action frame to the target AP */
1300	frame = os_malloc(sizeof(*frame) + len);
1301	if (frame == NULL)
1302		return -1;
1303	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1304	frame->packet_type = FT_PACKET_REQUEST;
1305	frame->action_length = host_to_le16(len);
1306	os_memcpy(frame->ap_address, sm->wpa_auth->addr, ETH_ALEN);
1307	os_memcpy(frame + 1, data, len);
1308
1309	wpa_ft_rrb_send(sm->wpa_auth, target_ap, (u8 *) frame,
1310			sizeof(*frame) + len);
1311	os_free(frame);
1312
1313	return 0;
1314}
1315
1316
1317static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid,
1318				     u16 auth_transaction, u16 resp,
1319				     const u8 *ies, size_t ies_len)
1320{
1321	struct wpa_state_machine *sm = ctx;
1322	wpa_printf(MSG_DEBUG, "FT: Over-the-DS RX request cb for " MACSTR,
1323		   MAC2STR(sm->addr));
1324	wpa_ft_send_rrb_auth_resp(sm, sm->ft_pending_current_ap, sm->addr,
1325				  WLAN_STATUS_SUCCESS, ies, ies_len);
1326}
1327
1328
1329static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
1330				 const u8 *current_ap, const u8 *sta_addr,
1331				 const u8 *body, size_t len)
1332{
1333	struct wpa_state_machine *sm;
1334	u16 status;
1335	u8 *resp_ies;
1336	size_t resp_ies_len;
1337	int res;
1338
1339	sm = wpa_ft_add_sta(wpa_auth, sta_addr);
1340	if (sm == NULL) {
1341		wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
1342			   "RRB Request");
1343		return -1;
1344	}
1345
1346	wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);
1347
1348	sm->ft_pending_cb = wpa_ft_rrb_rx_request_cb;
1349	sm->ft_pending_cb_ctx = sm;
1350	os_memcpy(sm->ft_pending_current_ap, current_ap, ETH_ALEN);
1351	res = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
1352				      &resp_ies_len);
1353	if (res < 0) {
1354		wpa_printf(MSG_DEBUG, "FT: No immediate response available - wait for pull response");
1355		return 0;
1356	}
1357	status = res;
1358
1359	res = wpa_ft_send_rrb_auth_resp(sm, current_ap, sta_addr, status,
1360					resp_ies, resp_ies_len);
1361	os_free(resp_ies);
1362	return res;
1363}
1364
1365
1366static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
1367				     const u8 *current_ap, const u8 *sta_addr,
1368				     u16 status, const u8 *resp_ies,
1369				     size_t resp_ies_len)
1370{
1371	struct wpa_authenticator *wpa_auth = sm->wpa_auth;
1372	size_t rlen;
1373	struct ft_rrb_frame *frame;
1374	u8 *pos;
1375
1376	wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
1377		   " CurrentAP=" MACSTR " status=%d",
1378		   MAC2STR(sm->addr), MAC2STR(current_ap), status);
1379	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
1380
1381	/* RRB - Forward action frame response to the Current AP */
1382
1383	/*
1384	 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
1385	 * Status_Code[2] FT Request action frame body[variable]
1386	 */
1387	rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;
1388
1389	frame = os_malloc(sizeof(*frame) + rlen);
1390	if (frame == NULL)
1391		return -1;
1392	frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1393	frame->packet_type = FT_PACKET_RESPONSE;
1394	frame->action_length = host_to_le16(rlen);
1395	os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN);
1396	pos = (u8 *) (frame + 1);
1397	*pos++ = WLAN_ACTION_FT;
1398	*pos++ = 2; /* Action: Response */
1399	os_memcpy(pos, sta_addr, ETH_ALEN);
1400	pos += ETH_ALEN;
1401	os_memcpy(pos, wpa_auth->addr, ETH_ALEN);
1402	pos += ETH_ALEN;
1403	WPA_PUT_LE16(pos, status);
1404	pos += 2;
1405	if (resp_ies)
1406		os_memcpy(pos, resp_ies, resp_ies_len);
1407
1408	wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
1409			sizeof(*frame) + rlen);
1410	os_free(frame);
1411
1412	return 0;
1413}
1414
1415
1416static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
1417			      const u8 *src_addr,
1418			      const u8 *data, size_t data_len)
1419{
1420	struct ft_r0kh_r1kh_pull_frame f;
1421	const u8 *crypt;
1422	u8 *plain;
1423	struct ft_remote_r1kh *r1kh;
1424	struct ft_r0kh_r1kh_resp_frame resp, r;
1425	u8 pmk_r0[PMK_LEN];
1426	int pairwise;
1427
1428	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull");
1429
1430	if (data_len < sizeof(f))
1431		return -1;
1432
1433	r1kh = wpa_auth->conf.r1kh_list;
1434	while (r1kh) {
1435		if (os_memcmp(r1kh->addr, src_addr, ETH_ALEN) == 0)
1436			break;
1437		r1kh = r1kh->next;
1438	}
1439	if (r1kh == NULL) {
1440		wpa_printf(MSG_DEBUG, "FT: No matching R1KH address found for "
1441			   "PMK-R1 pull source address " MACSTR,
1442			   MAC2STR(src_addr));
1443		return -1;
1444	}
1445
1446	crypt = data + offsetof(struct ft_r0kh_r1kh_pull_frame, nonce);
1447	os_memset(&f, 0, sizeof(f));
1448	plain = ((u8 *) &f) + offsetof(struct ft_r0kh_r1kh_pull_frame, nonce);
1449	/* aes_unwrap() does not support inplace decryption, so use a temporary
1450	 * buffer for the data. */
1451	if (aes_unwrap(r1kh->key, sizeof(r1kh->key),
1452		       (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
1453		       crypt, plain) < 0) {
1454		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
1455			   "request from " MACSTR, MAC2STR(src_addr));
1456		return -1;
1457	}
1458
1459	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
1460		    f.nonce, sizeof(f.nonce));
1461	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name",
1462		    f.pmk_r0_name, WPA_PMK_NAME_LEN);
1463	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
1464		   MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
1465
1466	os_memset(&resp, 0, sizeof(resp));
1467	resp.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1468	resp.packet_type = FT_PACKET_R0KH_R1KH_RESP;
1469	resp.data_length = host_to_le16(FT_R0KH_R1KH_RESP_DATA_LEN);
1470	os_memcpy(resp.ap_address, wpa_auth->addr, ETH_ALEN);
1471
1472	/* aes_wrap() does not support inplace encryption, so use a temporary
1473	 * buffer for the data. */
1474	os_memcpy(r.nonce, f.nonce, sizeof(f.nonce));
1475	os_memcpy(r.r1kh_id, f.r1kh_id, FT_R1KH_ID_LEN);
1476	os_memcpy(r.s1kh_id, f.s1kh_id, ETH_ALEN);
1477	if (wpa_ft_fetch_pmk_r0(wpa_auth, f.s1kh_id, f.pmk_r0_name, pmk_r0,
1478				&pairwise) < 0) {
1479		wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name found for "
1480			   "PMK-R1 pull");
1481		return -1;
1482	}
1483
1484	if (wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id,
1485			      r.pmk_r1, r.pmk_r1_name) < 0) {
1486		os_memset(pmk_r0, 0, PMK_LEN);
1487		return -1;
1488	}
1489	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN);
1490	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name,
1491		    WPA_PMK_NAME_LEN);
1492	r.pairwise = host_to_le16(pairwise);
1493	os_memset(r.pad, 0, sizeof(r.pad));
1494
1495	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
1496		     (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
1497		     r.nonce, resp.nonce) < 0) {
1498		os_memset(pmk_r0, 0, PMK_LEN);
1499		return -1;
1500	}
1501
1502	os_memset(pmk_r0, 0, PMK_LEN);
1503
1504	wpa_ft_rrb_send(wpa_auth, src_addr, (u8 *) &resp, sizeof(resp));
1505
1506	return 0;
1507}
1508
1509
1510static void ft_pull_resp_cb_finish(void *eloop_ctx, void *timeout_ctx)
1511{
1512	struct wpa_state_machine *sm = eloop_ctx;
1513	int res;
1514	u8 *resp_ies;
1515	size_t resp_ies_len;
1516	u16 status;
1517
1518	res = wpa_ft_process_auth_req(sm, wpabuf_head(sm->ft_pending_req_ies),
1519				      wpabuf_len(sm->ft_pending_req_ies),
1520				      &resp_ies, &resp_ies_len);
1521	wpabuf_free(sm->ft_pending_req_ies);
1522	sm->ft_pending_req_ies = NULL;
1523	if (res < 0)
1524		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
1525	status = res;
1526	wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR
1527		   " - status %u", MAC2STR(sm->addr), status);
1528
1529	sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr,
1530			  sm->ft_pending_auth_transaction + 1, status,
1531			  resp_ies, resp_ies_len);
1532	os_free(resp_ies);
1533}
1534
1535
1536static int ft_pull_resp_cb(struct wpa_state_machine *sm, void *ctx)
1537{
1538	struct ft_r0kh_r1kh_resp_frame *frame = ctx;
1539
1540	if (os_memcmp(frame->s1kh_id, sm->addr, ETH_ALEN) != 0 ||
1541	    os_memcmp(frame->nonce, sm->ft_pending_pull_nonce,
1542		      FT_R0KH_R1KH_PULL_NONCE_LEN) != 0 ||
1543	    sm->ft_pending_cb == NULL || sm->ft_pending_req_ies == NULL)
1544		return 0;
1545
1546	wpa_printf(MSG_DEBUG, "FT: Response to a pending pull request for "
1547		   MACSTR " - process from timeout", MAC2STR(sm->addr));
1548	eloop_register_timeout(0, 0, ft_pull_resp_cb_finish, sm, NULL);
1549	return 1;
1550}
1551
1552
1553static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
1554			      const u8 *src_addr,
1555			      const u8 *data, size_t data_len)
1556{
1557	struct ft_r0kh_r1kh_resp_frame f;
1558	const u8 *crypt;
1559	u8 *plain;
1560	struct ft_remote_r0kh *r0kh;
1561	int pairwise, res;
1562
1563	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response");
1564
1565	if (data_len < sizeof(f))
1566		return -1;
1567
1568	r0kh = wpa_auth->conf.r0kh_list;
1569	while (r0kh) {
1570		if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
1571			break;
1572		r0kh = r0kh->next;
1573	}
1574	if (r0kh == NULL) {
1575		wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
1576			   "PMK-R0 pull response source address " MACSTR,
1577			   MAC2STR(src_addr));
1578		return -1;
1579	}
1580
1581	crypt = data + offsetof(struct ft_r0kh_r1kh_resp_frame, nonce);
1582	os_memset(&f, 0, sizeof(f));
1583	plain = ((u8 *) &f) + offsetof(struct ft_r0kh_r1kh_resp_frame, nonce);
1584	/* aes_unwrap() does not support inplace decryption, so use a temporary
1585	 * buffer for the data. */
1586	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
1587		       (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
1588		       crypt, plain) < 0) {
1589		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
1590			   "response from " MACSTR, MAC2STR(src_addr));
1591		return -1;
1592	}
1593
1594	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
1595			    FT_R1KH_ID_LEN) != 0) {
1596		wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a "
1597			   "matching R1KH-ID");
1598		return -1;
1599	}
1600
1601	pairwise = le_to_host16(f.pairwise);
1602	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
1603		    f.nonce, sizeof(f.nonce));
1604	wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID="
1605		   MACSTR " pairwise=0x%x",
1606		   MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise);
1607	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 pull - PMK-R1",
1608			f.pmk_r1, PMK_LEN);
1609	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR1Name",
1610			f.pmk_r1_name, WPA_PMK_NAME_LEN);
1611
1612	res = wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
1613				  pairwise);
1614	wpa_printf(MSG_DEBUG, "FT: Look for pending pull request");
1615	wpa_auth_for_each_sta(wpa_auth, ft_pull_resp_cb, &f);
1616	os_memset(f.pmk_r1, 0, PMK_LEN);
1617
1618	return res ? 0 : -1;
1619}
1620
1621
1622static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth,
1623			      const u8 *src_addr,
1624			      const u8 *data, size_t data_len)
1625{
1626	struct ft_r0kh_r1kh_push_frame f;
1627	const u8 *crypt;
1628	u8 *plain;
1629	struct ft_remote_r0kh *r0kh;
1630	struct os_time now;
1631	os_time_t tsend;
1632	int pairwise;
1633
1634	wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 push");
1635
1636	if (data_len < sizeof(f))
1637		return -1;
1638
1639	r0kh = wpa_auth->conf.r0kh_list;
1640	while (r0kh) {
1641		if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
1642			break;
1643		r0kh = r0kh->next;
1644	}
1645	if (r0kh == NULL) {
1646		wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
1647			   "PMK-R0 push source address " MACSTR,
1648			   MAC2STR(src_addr));
1649		return -1;
1650	}
1651
1652	crypt = data + offsetof(struct ft_r0kh_r1kh_push_frame, timestamp);
1653	os_memset(&f, 0, sizeof(f));
1654	plain = ((u8 *) &f) + offsetof(struct ft_r0kh_r1kh_push_frame,
1655				       timestamp);
1656	/* aes_unwrap() does not support inplace decryption, so use a temporary
1657	 * buffer for the data. */
1658	if (aes_unwrap(r0kh->key, sizeof(r0kh->key),
1659		       (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
1660		       crypt, plain) < 0) {
1661		wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from "
1662			   MACSTR, MAC2STR(src_addr));
1663		return -1;
1664	}
1665
1666	os_get_time(&now);
1667	tsend = WPA_GET_LE32(f.timestamp);
1668	if ((now.sec > tsend && now.sec - tsend > 60) ||
1669	    (now.sec < tsend && tsend - now.sec > 60)) {
1670		wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not have a valid "
1671			   "timestamp: sender time %d own time %d\n",
1672			   (int) tsend, (int) now.sec);
1673		return -1;
1674	}
1675
1676	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
1677			    FT_R1KH_ID_LEN) != 0) {
1678		wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching "
1679			   "R1KH-ID (received " MACSTR " own " MACSTR ")",
1680			   MAC2STR(f.r1kh_id),
1681			   MAC2STR(wpa_auth->conf.r1_key_holder));
1682		return -1;
1683	}
1684
1685	pairwise = le_to_host16(f.pairwise);
1686	wpa_printf(MSG_DEBUG, "FT: PMK-R1 push - R1KH-ID=" MACSTR " S1KH-ID="
1687		   MACSTR " pairwise=0x%x",
1688		   MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise);
1689	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 push - PMK-R1",
1690			f.pmk_r1, PMK_LEN);
1691	wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 push - PMKR1Name",
1692			f.pmk_r1_name, WPA_PMK_NAME_LEN);
1693
1694	wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name,
1695			    pairwise);
1696	os_memset(f.pmk_r1, 0, PMK_LEN);
1697
1698	return 0;
1699}
1700
1701
1702int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
1703		  const u8 *data, size_t data_len)
1704{
1705	struct ft_rrb_frame *frame;
1706	u16 alen;
1707	const u8 *pos, *end, *start;
1708	u8 action;
1709	const u8 *sta_addr, *target_ap_addr;
1710
1711	wpa_printf(MSG_DEBUG, "FT: RRB received frame from remote AP " MACSTR,
1712		   MAC2STR(src_addr));
1713
1714	if (data_len < sizeof(*frame)) {
1715		wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (data_len=%lu)",
1716			   (unsigned long) data_len);
1717		return -1;
1718	}
1719
1720	pos = data;
1721	frame = (struct ft_rrb_frame *) pos;
1722	pos += sizeof(*frame);
1723
1724	alen = le_to_host16(frame->action_length);
1725	wpa_printf(MSG_DEBUG, "FT: RRB frame - frame_type=%d packet_type=%d "
1726		   "action_length=%d ap_address=" MACSTR,
1727		   frame->frame_type, frame->packet_type, alen,
1728		   MAC2STR(frame->ap_address));
1729
1730	if (frame->frame_type != RSN_REMOTE_FRAME_TYPE_FT_RRB) {
1731		/* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
1732		wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with "
1733			   "unrecognized type %d", frame->frame_type);
1734		return -1;
1735	}
1736
1737	if (alen > data_len - sizeof(*frame)) {
1738		wpa_printf(MSG_DEBUG, "FT: RRB frame too short for action "
1739			   "frame");
1740		return -1;
1741	}
1742
1743	if (frame->packet_type == FT_PACKET_R0KH_R1KH_PULL)
1744		return wpa_ft_rrb_rx_pull(wpa_auth, src_addr, data, data_len);
1745	if (frame->packet_type == FT_PACKET_R0KH_R1KH_RESP)
1746		return wpa_ft_rrb_rx_resp(wpa_auth, src_addr, data, data_len);
1747	if (frame->packet_type == FT_PACKET_R0KH_R1KH_PUSH)
1748		return wpa_ft_rrb_rx_push(wpa_auth, src_addr, data, data_len);
1749
1750	wpa_hexdump(MSG_MSGDUMP, "FT: RRB - FT Action frame", pos, alen);
1751
1752	if (alen < 1 + 1 + 2 * ETH_ALEN) {
1753		wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (not enough "
1754			   "room for Action Frame body); alen=%lu",
1755			   (unsigned long) alen);
1756		return -1;
1757	}
1758	start = pos;
1759	end = pos + alen;
1760
1761	if (*pos != WLAN_ACTION_FT) {
1762		wpa_printf(MSG_DEBUG, "FT: Unexpected Action frame category "
1763			   "%d", *pos);
1764		return -1;
1765	}
1766
1767	pos++;
1768	action = *pos++;
1769	sta_addr = pos;
1770	pos += ETH_ALEN;
1771	target_ap_addr = pos;
1772	pos += ETH_ALEN;
1773	wpa_printf(MSG_DEBUG, "FT: RRB Action Frame: action=%d sta_addr="
1774		   MACSTR " target_ap_addr=" MACSTR,
1775		   action, MAC2STR(sta_addr), MAC2STR(target_ap_addr));
1776
1777	if (frame->packet_type == FT_PACKET_REQUEST) {
1778		wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Request");
1779
1780		if (action != 1) {
1781			wpa_printf(MSG_DEBUG, "FT: Unexpected Action %d in "
1782				   "RRB Request", action);
1783			return -1;
1784		}
1785
1786		if (os_memcmp(target_ap_addr, wpa_auth->addr, ETH_ALEN) != 0) {
1787			wpa_printf(MSG_DEBUG, "FT: Target AP address in the "
1788				   "RRB Request does not match with own "
1789				   "address");
1790			return -1;
1791		}
1792
1793		if (wpa_ft_rrb_rx_request(wpa_auth, frame->ap_address,
1794					  sta_addr, pos, end - pos) < 0)
1795			return -1;
1796	} else if (frame->packet_type == FT_PACKET_RESPONSE) {
1797		u16 status_code;
1798
1799		if (end - pos < 2) {
1800			wpa_printf(MSG_DEBUG, "FT: Not enough room for status "
1801				   "code in RRB Response");
1802			return -1;
1803		}
1804		status_code = WPA_GET_LE16(pos);
1805		pos += 2;
1806
1807		wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response "
1808			   "(status_code=%d)", status_code);
1809
1810		if (wpa_ft_action_send(wpa_auth, sta_addr, start, alen) < 0)
1811			return -1;
1812	} else {
1813		wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with unknown "
1814			   "packet_type %d", frame->packet_type);
1815		return -1;
1816	}
1817
1818	if (end > pos) {
1819		wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end",
1820			    pos, end - pos);
1821	}
1822
1823	return 0;
1824}
1825
1826
1827static int wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
1828				  struct wpa_ft_pmk_r0_sa *pmk_r0,
1829				  struct ft_remote_r1kh *r1kh,
1830				  const u8 *s1kh_id, int pairwise)
1831{
1832	struct ft_r0kh_r1kh_push_frame frame, f;
1833	struct os_time now;
1834	const u8 *plain;
1835	u8 *crypt;
1836
1837	os_memset(&frame, 0, sizeof(frame));
1838	frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
1839	frame.packet_type = FT_PACKET_R0KH_R1KH_PUSH;
1840	frame.data_length = host_to_le16(FT_R0KH_R1KH_PUSH_DATA_LEN);
1841	os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);
1842
1843	/* aes_wrap() does not support inplace encryption, so use a temporary
1844	 * buffer for the data. */
1845	os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN);
1846	os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
1847	os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN);
1848	if (wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
1849			      s1kh_id, f.pmk_r1, f.pmk_r1_name) < 0)
1850		return -1;
1851	wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id));
1852	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN);
1853	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name,
1854		    WPA_PMK_NAME_LEN);
1855	os_get_time(&now);
1856	WPA_PUT_LE32(f.timestamp, now.sec);
1857	f.pairwise = host_to_le16(pairwise);
1858	os_memset(f.pad, 0, sizeof(f.pad));
1859	plain = ((const u8 *) &f) + offsetof(struct ft_r0kh_r1kh_push_frame,
1860					     timestamp);
1861	crypt = ((u8 *) &frame) + offsetof(struct ft_r0kh_r1kh_push_frame,
1862					   timestamp);
1863	if (aes_wrap(r1kh->key, sizeof(r1kh->key),
1864		     (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
1865		     plain, crypt) < 0)
1866		return -1;
1867
1868	wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame));
1869	return 0;
1870}
1871
1872
1873void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr)
1874{
1875	struct wpa_ft_pmk_r0_sa *r0;
1876	struct ft_remote_r1kh *r1kh;
1877
1878	if (!wpa_auth->conf.pmk_r1_push)
1879		return;
1880
1881	r0 = wpa_auth->ft_pmk_cache->pmk_r0;
1882	while (r0) {
1883		if (os_memcmp(r0->spa, addr, ETH_ALEN) == 0)
1884			break;
1885		r0 = r0->next;
1886	}
1887
1888	if (r0 == NULL || r0->pmk_r1_pushed)
1889		return;
1890	r0->pmk_r1_pushed = 1;
1891
1892	wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
1893		   "for STA " MACSTR, MAC2STR(addr));
1894
1895	r1kh = wpa_auth->conf.r1kh_list;
1896	while (r1kh) {
1897		wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr, r0->pairwise);
1898		r1kh = r1kh->next;
1899	}
1900}
1901
1902#endif /* CONFIG_IEEE80211R_AP */
1903