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