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