]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/wpa_auth_ft.c
FT: PMKID derivation using SHA384-based AKM
[thirdparty/hostap.git] / src / ap / wpa_auth_ft.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd - IEEE 802.11r - Fast BSS Transition
c22bb5bb 3 * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
6226e38d 9#include "utils/includes.h"
6fc6879b 10
6226e38d 11#include "utils/common.h"
692ec305 12#include "utils/eloop.h"
76967603 13#include "utils/list.h"
81f4f619
JM
14#include "common/ieee802_11_defs.h"
15#include "common/ieee802_11_common.h"
245fc96e
MB
16#include "crypto/aes.h"
17#include "crypto/aes_siv.h"
03da66bd 18#include "crypto/aes_wrap.h"
a3e18dbb 19#include "crypto/sha384.h"
3642c431 20#include "crypto/random.h"
6226e38d 21#include "ap_config.h"
6fc6879b 22#include "ieee802_11.h"
1057d78e 23#include "wmm.h"
6226e38d 24#include "wpa_auth.h"
6fc6879b 25#include "wpa_auth_i.h"
6fc6879b
JM
26
27
4ec1fd8e 28#ifdef CONFIG_IEEE80211R_AP
6fc6879b 29
eefe8630
MB
30const unsigned int ftRRBseqTimeout = 10;
31const unsigned int ftRRBmaxQueueLen = 100;
32
33
692ec305
JM
34static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
35 const u8 *current_ap, const u8 *sta_addr,
36 u16 status, const u8 *resp_ies,
37 size_t resp_ies_len);
3a46cf93
MB
38static void ft_finish_pull(struct wpa_state_machine *sm);
39static void wpa_ft_expire_pull(void *eloop_ctx, void *timeout_ctx);
eefe8630 40static void wpa_ft_rrb_seq_timeout(void *eloop_ctx, void *timeout_ctx);
692ec305 41
245fc96e
MB
42struct tlv_list {
43 u16 type;
44 size_t len;
45 const u8 *data;
46};
47
48
49/**
50 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
51 * @key: AES-SIV key for AEAD
52 * @key_len: Length of key in octets
53 * @enc: Pointer to encrypted TLVs
54 * @enc_len: Length of encrypted TLVs in octets
55 * @auth: Pointer to authenticated TLVs
56 * @auth_len: Length of authenticated TLVs in octets
57 * @src_addr: MAC address of the frame sender
58 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
59 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
60 * needs to be freed by the caller if not NULL;
61 * will only be returned on success
62 * @plain_len: Pointer to return the length of the allocated plaintext buffer
63 * in octets
64 * Returns: 0 on success, -1 on error
65 */
66static int wpa_ft_rrb_decrypt(const u8 *key, const size_t key_len,
67 const u8 *enc, const size_t enc_len,
68 const u8 *auth, const size_t auth_len,
69 const u8 *src_addr, u8 type,
70 u8 **plain, size_t *plain_size)
71{
72 const u8 *ad[3] = { src_addr, auth, &type };
73 size_t ad_len[3] = { ETH_ALEN, auth_len, sizeof(type) };
74
75 wpa_hexdump_key(MSG_DEBUG, "FT(RRB): decrypt using key", key, key_len);
76
77 if (!key) { /* skip decryption */
78 *plain = os_memdup(enc, enc_len);
79 if (enc_len > 0 && !*plain)
80 goto err;
81
82 *plain_size = enc_len;
83
84 return 0;
85 }
86
87 *plain = NULL;
88
89 /* SIV overhead */
90 if (enc_len < AES_BLOCK_SIZE)
91 goto err;
92
93 *plain = os_zalloc(enc_len - AES_BLOCK_SIZE);
94 if (!*plain)
95 goto err;
96
97 if (aes_siv_decrypt(key, key_len, enc, enc_len, 3, ad, ad_len,
98 *plain) < 0)
99 goto err;
100
101 *plain_size = enc_len - AES_BLOCK_SIZE;
102 wpa_hexdump_key(MSG_DEBUG, "FT(RRB): decrypted TLVs",
103 *plain, *plain_size);
104 return 0;
105err:
106 os_free(*plain);
107 *plain = NULL;
108 *plain_size = 0;
109
110 wpa_printf(MSG_ERROR, "FT(RRB): Failed to decrypt");
111
112 return -1;
113}
114
115
116/* get first tlv record in packet matching type
117 * @data (decrypted) packet
118 * @return 0 on success else -1
119 */
120static int wpa_ft_rrb_get_tlv(const u8 *plain, size_t plain_len,
121 u16 type, size_t *tlv_len, const u8 **tlv_data)
122{
123 const struct ft_rrb_tlv *f;
124 size_t left;
125 le16 type16;
126 size_t len;
127
128 left = plain_len;
129 type16 = host_to_le16(type);
130
131 while (left >= sizeof(*f)) {
132 f = (const struct ft_rrb_tlv *) plain;
133
134 left -= sizeof(*f);
135 plain += sizeof(*f);
136 len = le_to_host16(f->len);
137
138 if (left < len) {
139 wpa_printf(MSG_DEBUG, "FT: RRB message truncated");
140 break;
141 }
142
143 if (f->type == type16) {
144 *tlv_len = len;
145 *tlv_data = plain;
146 return 0;
147 }
148
149 left -= len;
150 plain += len;
151 }
152
153 return -1;
154}
155
156
157static void wpa_ft_rrb_dump(const u8 *plain, const size_t plain_len)
158{
159 const struct ft_rrb_tlv *f;
160 size_t left;
161 size_t len;
162
163 left = plain_len;
164
165 wpa_printf(MSG_DEBUG, "FT: RRB dump message");
166 while (left >= sizeof(*f)) {
167 f = (const struct ft_rrb_tlv *) plain;
168
169 left -= sizeof(*f);
170 plain += sizeof(*f);
171 len = le_to_host16(f->len);
172
173 wpa_printf(MSG_DEBUG, "FT: RRB TLV type = %d, len = %zu",
174 le_to_host16(f->type), len);
175
176 if (left < len) {
177 wpa_printf(MSG_DEBUG,
178 "FT: RRB message truncated: left %zu bytes, need %zu",
179 left, len);
180 break;
181 }
182
183 wpa_hexdump(MSG_DEBUG, "FT: RRB TLV data", plain, len);
184
185 left -= len;
186 plain += len;
187 }
188
189 if (left > 0)
190 wpa_hexdump(MSG_DEBUG, "FT: RRB TLV padding", plain, left);
191
192 wpa_printf(MSG_DEBUG, "FT: RRB dump message end");
193}
194
195
17010c38
MB
196static int cmp_int(const void *a, const void *b)
197{
198 int x, y;
199
200 x = *((int *) a);
201 y = *((int *) b);
202 return x - y;
203}
204
205
206static int wpa_ft_rrb_get_tlv_vlan(const u8 *plain, const size_t plain_len,
207 struct vlan_description *vlan)
208{
209 struct ft_rrb_tlv *f;
210 size_t left;
211 size_t len;
212 int taggedidx;
213 int vlan_id;
214 int type;
215
216 left = plain_len;
217 taggedidx = 0;
218 os_memset(vlan, 0, sizeof(*vlan));
219
220 while (left >= sizeof(*f)) {
221 f = (struct ft_rrb_tlv *) plain;
222
223 left -= sizeof(*f);
224 plain += sizeof(*f);
225
226 len = le_to_host16(f->len);
227 type = le_to_host16(f->type);
228
229 if (left < len) {
230 wpa_printf(MSG_DEBUG, "FT: RRB message truncated");
231 return -1;
232 }
233
234 if (type != FT_RRB_VLAN_UNTAGGED && type != FT_RRB_VLAN_TAGGED)
235 goto skip;
236
237 if (type == FT_RRB_VLAN_UNTAGGED && len != sizeof(le16)) {
238 wpa_printf(MSG_DEBUG,
239 "FT: RRB VLAN_UNTAGGED invalid length");
240 return -1;
241 }
242
243 if (type == FT_RRB_VLAN_TAGGED && len % sizeof(le16) != 0) {
244 wpa_printf(MSG_DEBUG,
245 "FT: RRB VLAN_TAGGED invalid length");
246 return -1;
247 }
248
249 while (len >= sizeof(le16)) {
250 vlan_id = WPA_GET_LE16(plain);
251 plain += sizeof(le16);
252 left -= sizeof(le16);
253 len -= sizeof(le16);
254
255 if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID) {
256 wpa_printf(MSG_DEBUG,
257 "FT: RRB VLAN ID invalid %d",
258 vlan_id);
259 continue;
260 }
261
262 if (type == FT_RRB_VLAN_UNTAGGED)
263 vlan->untagged = vlan_id;
264
265 if (type == FT_RRB_VLAN_TAGGED &&
266 taggedidx < MAX_NUM_TAGGED_VLAN) {
267 vlan->tagged[taggedidx] = vlan_id;
268 taggedidx++;
269 } else if (type == FT_RRB_VLAN_TAGGED) {
270 wpa_printf(MSG_DEBUG, "FT: RRB too many VLANs");
271 }
272 }
273
274 skip:
275 left -= len;
276 plain += len;
277 }
278
279 if (taggedidx)
280 qsort(vlan->tagged, taggedidx, sizeof(int), cmp_int);
281
282 vlan->notempty = vlan->untagged || vlan->tagged[0];
283
284 return 0;
285}
286
287
245fc96e
MB
288static size_t wpa_ft_tlv_len(const struct tlv_list *tlvs)
289{
290 size_t tlv_len = 0;
291 int i;
292
293 if (!tlvs)
294 return 0;
295
296 for (i = 0; tlvs[i].type != FT_RRB_LAST_EMPTY; i++) {
297 tlv_len += sizeof(struct ft_rrb_tlv);
298 tlv_len += tlvs[i].len;
299 }
300
301 return tlv_len;
302}
303
304
305static size_t wpa_ft_tlv_lin(const struct tlv_list *tlvs, u8 *start,
306 u8 *endpos)
307{
308 int i;
309 size_t tlv_len;
310 struct ft_rrb_tlv *hdr;
311 u8 *pos;
312
313 if (!tlvs)
314 return 0;
315
316 tlv_len = 0;
317 pos = start;
318 for (i = 0; tlvs[i].type != FT_RRB_LAST_EMPTY; i++) {
319 if (tlv_len + sizeof(*hdr) > (size_t) (endpos - start))
320 return tlv_len;
321 tlv_len += sizeof(*hdr);
322 hdr = (struct ft_rrb_tlv *) pos;
323 hdr->type = host_to_le16(tlvs[i].type);
324 hdr->len = host_to_le16(tlvs[i].len);
325 pos = start + tlv_len;
326
327 if (tlv_len + tlvs[i].len > (size_t) (endpos - start))
328 return tlv_len;
069b4e30
MB
329 if (tlvs[i].len == 0)
330 continue;
245fc96e
MB
331 tlv_len += tlvs[i].len;
332 os_memcpy(pos, tlvs[i].data, tlvs[i].len);
333 pos = start + tlv_len;
334 }
335
336 return tlv_len;
337}
338
339
17010c38
MB
340static size_t wpa_ft_vlan_len(const struct vlan_description *vlan)
341{
342 size_t tlv_len = 0;
343 int i;
344
345 if (!vlan || !vlan->notempty)
346 return 0;
347
348 if (vlan->untagged) {
349 tlv_len += sizeof(struct ft_rrb_tlv);
350 tlv_len += sizeof(le16);
351 }
352 if (vlan->tagged[0])
353 tlv_len += sizeof(struct ft_rrb_tlv);
354 for (i = 0; i < MAX_NUM_TAGGED_VLAN && vlan->tagged[i]; i++)
355 tlv_len += sizeof(le16);
356
357 return tlv_len;
358}
359
360
361static size_t wpa_ft_vlan_lin(const struct vlan_description *vlan,
362 u8 *start, u8 *endpos)
363{
364 size_t tlv_len;
365 int i, len;
366 struct ft_rrb_tlv *hdr;
367 u8 *pos = start;
368
369 if (!vlan || !vlan->notempty)
370 return 0;
371
372 tlv_len = 0;
373 if (vlan->untagged) {
374 tlv_len += sizeof(*hdr);
375 if (start + tlv_len > endpos)
376 return tlv_len;
377 hdr = (struct ft_rrb_tlv *) pos;
378 hdr->type = host_to_le16(FT_RRB_VLAN_UNTAGGED);
379 hdr->len = host_to_le16(sizeof(le16));
380 pos = start + tlv_len;
381
382 tlv_len += sizeof(le16);
383 if (start + tlv_len > endpos)
384 return tlv_len;
385 WPA_PUT_LE16(pos, vlan->untagged);
386 pos = start + tlv_len;
387 }
388
389 if (!vlan->tagged[0])
390 return tlv_len;
391
392 tlv_len += sizeof(*hdr);
393 if (start + tlv_len > endpos)
394 return tlv_len;
395 hdr = (struct ft_rrb_tlv *) pos;
396 hdr->type = host_to_le16(FT_RRB_VLAN_TAGGED);
397 len = 0; /* len is computed below */
398 pos = start + tlv_len;
399
400 for (i = 0; i < MAX_NUM_TAGGED_VLAN && vlan->tagged[i]; i++) {
401 tlv_len += sizeof(le16);
402 if (start + tlv_len > endpos)
403 break;
404 len += sizeof(le16);
405 WPA_PUT_LE16(pos, vlan->tagged[i]);
406 pos = start + tlv_len;
407 }
408
409 hdr->len = host_to_le16(len);
410
411 return tlv_len;
412}
413
414
245fc96e
MB
415static int wpa_ft_rrb_lin(const struct tlv_list *tlvs1,
416 const struct tlv_list *tlvs2,
17010c38 417 const struct vlan_description *vlan,
245fc96e
MB
418 u8 **plain, size_t *plain_len)
419{
420 u8 *pos, *endpos;
421 size_t tlv_len;
422
423 tlv_len = wpa_ft_tlv_len(tlvs1);
424 tlv_len += wpa_ft_tlv_len(tlvs2);
17010c38 425 tlv_len += wpa_ft_vlan_len(vlan);
245fc96e
MB
426
427 *plain_len = tlv_len;
428 *plain = os_zalloc(tlv_len);
429 if (!*plain) {
430 wpa_printf(MSG_ERROR, "FT: Failed to allocate plaintext");
431 goto err;
432 }
433
434 pos = *plain;
435 endpos = *plain + tlv_len;
436 pos += wpa_ft_tlv_lin(tlvs1, pos, endpos);
437 pos += wpa_ft_tlv_lin(tlvs2, pos, endpos);
17010c38 438 pos += wpa_ft_vlan_lin(vlan, pos, endpos);
245fc96e
MB
439
440 /* sanity check */
441 if (pos != endpos) {
442 wpa_printf(MSG_ERROR, "FT: Length error building RRB");
443 goto err;
444 }
445
446 return 0;
447
448err:
449 os_free(*plain);
450 *plain = NULL;
451 *plain_len = 0;
452 return -1;
453}
454
455
456static int wpa_ft_rrb_encrypt(const u8 *key, const size_t key_len,
457 const u8 *plain, const size_t plain_len,
458 const u8 *auth, const size_t auth_len,
459 const u8 *src_addr, u8 type, u8 *enc)
460{
461 const u8 *ad[3] = { src_addr, auth, &type };
462 size_t ad_len[3] = { ETH_ALEN, auth_len, sizeof(type) };
463
464 wpa_hexdump_key(MSG_DEBUG, "FT(RRB): plaintext message",
465 plain, plain_len);
466 wpa_hexdump_key(MSG_DEBUG, "FT(RRB): encrypt using key", key, key_len);
467
468 if (!key) {
469 /* encryption not needed, return plaintext as packet */
470 os_memcpy(enc, plain, plain_len);
471 } else if (aes_siv_encrypt(key, key_len, plain, plain_len,
472 3, ad, ad_len, enc) < 0) {
473 wpa_printf(MSG_ERROR, "FT: Failed to encrypt RRB-OUI message");
474 return -1;
475 }
476
477 return 0;
478}
479
480
481/**
482 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
483 * @key: AES-SIV key for AEAD
484 * @key_len: Length of key in octets
485 * @tlvs_enc0: First set of to-be-encrypted TLVs
486 * @tlvs_enc1: Second set of to-be-encrypted TLVs
487 * @tlvs_auth: Set of to-be-authenticated TLVs
488 * @src_addr: MAC address of the frame sender
489 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
490 * @packet Pointer to return the pointer to the allocated packet buffer;
491 * needs to be freed by the caller if not null;
492 * will only be returned on success
493 * @packet_len: Pointer to return the length of the allocated buffer in octets
494 * Returns: 0 on success, -1 on error
495 */
496static int wpa_ft_rrb_build(const u8 *key, const size_t key_len,
497 const struct tlv_list *tlvs_enc0,
498 const struct tlv_list *tlvs_enc1,
499 const struct tlv_list *tlvs_auth,
17010c38 500 const struct vlan_description *vlan,
245fc96e
MB
501 const u8 *src_addr, u8 type,
502 u8 **packet, size_t *packet_len)
503{
504 u8 *plain = NULL, *auth = NULL, *pos;
505 size_t plain_len = 0, auth_len = 0;
506 int ret = -1;
507
17010c38 508 if (wpa_ft_rrb_lin(tlvs_enc0, tlvs_enc1, vlan, &plain, &plain_len) < 0)
245fc96e
MB
509 goto out;
510
17010c38 511 if (wpa_ft_rrb_lin(tlvs_auth, NULL, NULL, &auth, &auth_len) < 0)
245fc96e
MB
512 goto out;
513
514 *packet_len = sizeof(u16) + auth_len + plain_len;
515 if (key)
516 *packet_len += AES_BLOCK_SIZE;
517 *packet = os_zalloc(*packet_len);
518 if (!*packet)
519 goto out;
520
521 pos = *packet;
522 WPA_PUT_LE16(pos, auth_len);
523 pos += 2;
524 os_memcpy(pos, auth, auth_len);
525 pos += auth_len;
526 if (wpa_ft_rrb_encrypt(key, key_len, plain, plain_len, auth,
527 auth_len, src_addr, type, pos) < 0)
528 goto out;
529
530 ret = 0;
531
532out:
533 bin_clear_free(plain, plain_len);
534 os_free(auth);
535
536 if (ret) {
537 wpa_printf(MSG_ERROR, "FT: Failed to build RRB-OUI message");
538 os_free(*packet);
539 *packet = NULL;
540 *packet_len = 0;
541 }
542
543 return ret;
544}
545
546
547#define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
548 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
549 &f_##field##_len, &f_##field) < 0 || \
550 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
551 wpa_printf(MSG_INFO, "FT: Missing required " #field \
552 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
553 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
554 goto out; \
555 } \
556} while (0)
557
558#define RRB_GET(type, field, txt, checklength) \
559 RRB_GET_SRC(plain, type, field, txt, checklength)
560#define RRB_GET_AUTH(type, field, txt, checklength) \
561 RRB_GET_SRC(auth, type, field, txt, checklength)
562
563#define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
564 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
565 &f_##field##_len, &f_##field) < 0 || \
566 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
567 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
568 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
569 f_##field##_len = 0; \
570 f_##field = NULL; \
571 } \
572} while (0)
573
574#define RRB_GET_OPTIONAL(type, field, txt, checklength) \
575 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
576#define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
577 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
692ec305 578
6fc6879b
JM
579static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
580 const u8 *data, size_t data_len)
581{
cef8fac0 582 if (wpa_auth->cb->send_ether == NULL)
6fc6879b 583 return -1;
67ccef7e 584 wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst));
cef8fac0
JB
585 return wpa_auth->cb->send_ether(wpa_auth->cb_ctx, dst, ETH_P_RRB,
586 data, data_len);
6fc6879b
JM
587}
588
589
50bd8e0a
MB
590static int wpa_ft_rrb_oui_send(struct wpa_authenticator *wpa_auth,
591 const u8 *dst, u8 oui_suffix,
592 const u8 *data, size_t data_len)
593{
594 if (!wpa_auth->cb->send_oui)
595 return -1;
596 wpa_printf(MSG_DEBUG, "FT: RRB-OUI type %u send to " MACSTR,
597 oui_suffix, MAC2STR(dst));
598 return wpa_auth->cb->send_oui(wpa_auth->cb_ctx, dst, oui_suffix, data,
599 data_len);
600}
601
602
6fc6879b
JM
603static int wpa_ft_action_send(struct wpa_authenticator *wpa_auth,
604 const u8 *dst, const u8 *data, size_t data_len)
605{
cef8fac0 606 if (wpa_auth->cb->send_ft_action == NULL)
6fc6879b 607 return -1;
cef8fac0
JB
608 return wpa_auth->cb->send_ft_action(wpa_auth->cb_ctx, dst,
609 data, data_len);
6fc6879b
JM
610}
611
612
96590564
MB
613static const u8 * wpa_ft_get_psk(struct wpa_authenticator *wpa_auth,
614 const u8 *addr, const u8 *p2p_dev_addr,
615 const u8 *prev_psk)
616{
cef8fac0 617 if (wpa_auth->cb->get_psk == NULL)
96590564 618 return NULL;
cef8fac0 619 return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
7a12edd1 620 prev_psk, NULL);
96590564
MB
621}
622
623
6fc6879b
JM
624static struct wpa_state_machine *
625wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
626{
cef8fac0 627 if (wpa_auth->cb->add_sta == NULL)
6fc6879b 628 return NULL;
cef8fac0 629 return wpa_auth->cb->add_sta(wpa_auth->cb_ctx, sta_addr);
6fc6879b
JM
630}
631
632
17010c38
MB
633static int wpa_ft_set_vlan(struct wpa_authenticator *wpa_auth,
634 const u8 *sta_addr, struct vlan_description *vlan)
635{
636 if (!wpa_auth->cb->set_vlan)
637 return -1;
638 return wpa_auth->cb->set_vlan(wpa_auth->cb_ctx, sta_addr, vlan);
639}
640
641
642static int wpa_ft_get_vlan(struct wpa_authenticator *wpa_auth,
643 const u8 *sta_addr, struct vlan_description *vlan)
644{
645 if (!wpa_auth->cb->get_vlan)
646 return -1;
647 return wpa_auth->cb->get_vlan(wpa_auth->cb_ctx, sta_addr, vlan);
648}
649
650
069b4e30
MB
651static int
652wpa_ft_set_identity(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
653 const u8 *identity, size_t identity_len)
654{
655 if (!wpa_auth->cb->set_identity)
656 return -1;
657 return wpa_auth->cb->set_identity(wpa_auth->cb_ctx, sta_addr, identity,
658 identity_len);
659}
660
661
662static size_t
663wpa_ft_get_identity(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
664 const u8 **buf)
665{
666 *buf = NULL;
667 if (!wpa_auth->cb->get_identity)
668 return 0;
669 return wpa_auth->cb->get_identity(wpa_auth->cb_ctx, sta_addr, buf);
670}
671
672
673static int
674wpa_ft_set_radius_cui(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
675 const u8 *radius_cui, size_t radius_cui_len)
676{
677 if (!wpa_auth->cb->set_radius_cui)
678 return -1;
679 return wpa_auth->cb->set_radius_cui(wpa_auth->cb_ctx, sta_addr,
680 radius_cui, radius_cui_len);
681}
682
683
684static size_t
685wpa_ft_get_radius_cui(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
686 const u8 **buf)
687{
688 *buf = NULL;
689 if (!wpa_auth->cb->get_radius_cui)
690 return 0;
691 return wpa_auth->cb->get_radius_cui(wpa_auth->cb_ctx, sta_addr, buf);
692}
693
694
a6509e85
MB
695static void
696wpa_ft_set_session_timeout(struct wpa_authenticator *wpa_auth,
697 const u8 *sta_addr, int session_timeout)
698{
699 if (!wpa_auth->cb->set_session_timeout)
700 return;
701 wpa_auth->cb->set_session_timeout(wpa_auth->cb_ctx, sta_addr,
702 session_timeout);
703}
704
705
706static int
707wpa_ft_get_session_timeout(struct wpa_authenticator *wpa_auth,
708 const u8 *sta_addr)
709{
710 if (!wpa_auth->cb->get_session_timeout)
711 return 0;
712 return wpa_auth->cb->get_session_timeout(wpa_auth->cb_ctx, sta_addr);
713}
714
715
88b32a99
SP
716static int wpa_ft_add_tspec(struct wpa_authenticator *wpa_auth,
717 const u8 *sta_addr,
718 u8 *tspec_ie, size_t tspec_ielen)
719{
cef8fac0 720 if (wpa_auth->cb->add_tspec == NULL) {
006309b5 721 wpa_printf(MSG_DEBUG, "FT: add_tspec is not initialized");
88b32a99
SP
722 return -1;
723 }
cef8fac0
JB
724 return wpa_auth->cb->add_tspec(wpa_auth->cb_ctx, sta_addr, tspec_ie,
725 tspec_ielen);
88b32a99
SP
726}
727
728
6fc6879b
JM
729int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
730{
731 u8 *pos = buf;
732 u8 capab;
733 if (len < 2 + sizeof(struct rsn_mdie))
734 return -1;
735
736 *pos++ = WLAN_EID_MOBILITY_DOMAIN;
737 *pos++ = MOBILITY_DOMAIN_ID_LEN + 1;
738 os_memcpy(pos, conf->mobility_domain, MOBILITY_DOMAIN_ID_LEN);
739 pos += MOBILITY_DOMAIN_ID_LEN;
d7956add
SP
740 capab = 0;
741 if (conf->ft_over_ds)
742 capab |= RSN_FT_CAPAB_FT_OVER_DS;
6fc6879b
JM
743 *pos++ = capab;
744
745 return pos - buf;
746}
747
748
86dfabb8
JM
749int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
750 size_t r0kh_id_len,
751 const u8 *anonce, const u8 *snonce,
752 u8 *buf, size_t len, const u8 *subelem,
753 size_t subelem_len)
6fc6879b
JM
754{
755 u8 *pos = buf, *ielen;
756 struct rsn_ftie *hdr;
757
758 if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
759 subelem_len)
760 return -1;
761
762 *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
763 ielen = pos++;
764
765 hdr = (struct rsn_ftie *) pos;
766 os_memset(hdr, 0, sizeof(*hdr));
767 pos += sizeof(*hdr);
768 WPA_PUT_LE16(hdr->mic_control, 0);
769 if (anonce)
770 os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
771 if (snonce)
772 os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
773
774 /* Optional Parameters */
775 *pos++ = FTIE_SUBELEM_R1KH_ID;
776 *pos++ = FT_R1KH_ID_LEN;
777 os_memcpy(pos, conf->r1_key_holder, FT_R1KH_ID_LEN);
778 pos += FT_R1KH_ID_LEN;
779
780 if (r0kh_id) {
781 *pos++ = FTIE_SUBELEM_R0KH_ID;
782 *pos++ = r0kh_id_len;
783 os_memcpy(pos, r0kh_id, r0kh_id_len);
784 pos += r0kh_id_len;
785 }
786
787 if (subelem) {
788 os_memcpy(pos, subelem, subelem_len);
789 pos += subelem_len;
790 }
791
792 *ielen = pos - buf - 2;
793
794 return pos - buf;
795}
796
797
eefe8630
MB
798/* A packet to be handled after seq response */
799struct ft_remote_item {
800 struct dl_list list;
801
802 u8 nonce[FT_RRB_NONCE_LEN];
803 struct os_reltime nonce_ts;
804
805 u8 src_addr[ETH_ALEN];
806 u8 *enc;
807 size_t enc_len;
808 u8 *auth;
809 size_t auth_len;
810 int (*cb)(struct wpa_authenticator *wpa_auth,
811 const u8 *src_addr,
812 const u8 *enc, size_t enc_len,
813 const u8 *auth, size_t auth_len,
814 int no_defer);
815};
816
817
818static void wpa_ft_rrb_seq_free(struct ft_remote_item *item)
819{
820 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout, ELOOP_ALL_CTX, item);
821 dl_list_del(&item->list);
822 bin_clear_free(item->enc, item->enc_len);
823 os_free(item->auth);
824 os_free(item);
825}
826
827
828static void wpa_ft_rrb_seq_flush(struct wpa_authenticator *wpa_auth,
829 struct ft_remote_seq *rkh_seq, int cb)
830{
831 struct ft_remote_item *item, *n;
832
833 dl_list_for_each_safe(item, n, &rkh_seq->rx.queue,
834 struct ft_remote_item, list) {
835 if (cb && item->cb)
836 item->cb(wpa_auth, item->src_addr, item->enc,
837 item->enc_len, item->auth, item->auth_len, 1);
838 wpa_ft_rrb_seq_free(item);
839 }
840}
841
842
843static void wpa_ft_rrb_seq_timeout(void *eloop_ctx, void *timeout_ctx)
844{
845 struct ft_remote_item *item = timeout_ctx;
846
847 wpa_ft_rrb_seq_free(item);
848}
849
850
851static int
852wpa_ft_rrb_seq_req(struct wpa_authenticator *wpa_auth,
853 struct ft_remote_seq *rkh_seq, const u8 *src_addr,
854 const u8 *f_r0kh_id, size_t f_r0kh_id_len,
855 const u8 *f_r1kh_id, const u8 *key, size_t key_len,
856 const u8 *enc, size_t enc_len,
857 const u8 *auth, size_t auth_len,
858 int (*cb)(struct wpa_authenticator *wpa_auth,
859 const u8 *src_addr,
860 const u8 *enc, size_t enc_len,
861 const u8 *auth, size_t auth_len,
862 int no_defer))
863{
864 struct ft_remote_item *item = NULL;
865 u8 *packet = NULL;
866 size_t packet_len;
867 struct tlv_list seq_req_auth[] = {
868 { .type = FT_RRB_NONCE, .len = FT_RRB_NONCE_LEN,
869 .data = NULL /* to be filled: item->nonce */ },
870 { .type = FT_RRB_R0KH_ID, .len = f_r0kh_id_len,
871 .data = f_r0kh_id },
872 { .type = FT_RRB_R1KH_ID, .len = FT_R1KH_ID_LEN,
873 .data = f_r1kh_id },
874 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
875 };
876
877 if (dl_list_len(&rkh_seq->rx.queue) >= ftRRBmaxQueueLen) {
878 wpa_printf(MSG_DEBUG, "FT: Sequence number queue too long");
879 goto err;
880 }
881
882 item = os_zalloc(sizeof(*item));
883 if (!item)
884 goto err;
885
886 os_memcpy(item->src_addr, src_addr, ETH_ALEN);
887 item->cb = cb;
888
889 if (random_get_bytes(item->nonce, FT_RRB_NONCE_LEN) < 0) {
890 wpa_printf(MSG_DEBUG, "FT: Seq num nonce: out of random bytes");
891 goto err;
892 }
893
894 if (os_get_reltime(&item->nonce_ts) < 0)
895 goto err;
896
897 if (enc && enc_len > 0) {
898 item->enc = os_memdup(enc, enc_len);
899 item->enc_len = enc_len;
900 if (!item->enc)
901 goto err;
902 }
903
904 if (auth && auth_len > 0) {
905 item->auth = os_memdup(auth, auth_len);
906 item->auth_len = auth_len;
907 if (!item->auth)
908 goto err;
909 }
910
911 eloop_register_timeout(ftRRBseqTimeout, 0, wpa_ft_rrb_seq_timeout,
912 wpa_auth, item);
913
914 seq_req_auth[0].data = item->nonce;
915
17010c38 916 if (wpa_ft_rrb_build(key, key_len, NULL, NULL, seq_req_auth, NULL,
eefe8630
MB
917 wpa_auth->addr, FT_PACKET_R0KH_R1KH_SEQ_REQ,
918 &packet, &packet_len) < 0) {
919 item = NULL; /* some other seq resp might still accept this */
920 goto err;
921 }
922
923 dl_list_add(&rkh_seq->rx.queue, &item->list);
924
925 wpa_ft_rrb_oui_send(wpa_auth, src_addr, FT_PACKET_R0KH_R1KH_SEQ_REQ,
926 packet, packet_len);
927
928 os_free(packet);
929
930 return 0;
931err:
932 wpa_printf(MSG_DEBUG, "FT: Failed to send sequence number request");
933 if (item) {
934 os_free(item->auth);
935 bin_clear_free(item->enc, item->enc_len);
936 os_free(item);
937 }
938
939 return -1;
940}
941
942
943#define FT_RRB_SEQ_OK 0
944#define FT_RRB_SEQ_DROP 1
945#define FT_RRB_SEQ_DEFER 2
946
947static int
948wpa_ft_rrb_seq_chk(struct ft_remote_seq *rkh_seq, const u8 *src_addr,
949 const u8 *enc, size_t enc_len,
950 const u8 *auth, size_t auth_len,
951 const char *msgtype, int no_defer)
952{
953 const u8 *f_seq;
954 size_t f_seq_len;
955 const struct ft_rrb_seq *msg_both;
956 u32 msg_seq, msg_off, rkh_off;
957 struct os_reltime now;
958 unsigned int i;
959
960 RRB_GET_AUTH(FT_RRB_SEQ, seq, msgtype, sizeof(*msg_both));
961 wpa_hexdump(MSG_DEBUG, "FT: sequence number", f_seq, f_seq_len);
962 msg_both = (const struct ft_rrb_seq *) f_seq;
963
964 if (rkh_seq->rx.num_last == 0) {
965 /* first packet from remote */
966 goto defer;
967 }
968
969 if (le_to_host32(msg_both->dom) != rkh_seq->rx.dom) {
970 /* remote might have rebooted */
971 goto defer;
972 }
973
974 if (os_get_reltime(&now) == 0) {
975 u32 msg_ts_now_remote, msg_ts_off;
976 struct os_reltime now_remote;
977
978 os_reltime_sub(&now, &rkh_seq->rx.time_offset, &now_remote);
979 msg_ts_now_remote = now_remote.sec;
980 msg_ts_off = le_to_host32(msg_both->ts) -
981 (msg_ts_now_remote - ftRRBseqTimeout);
982 if (msg_ts_off > 2 * ftRRBseqTimeout)
983 goto defer;
984 }
985
986 msg_seq = le_to_host32(msg_both->seq);
987 rkh_off = rkh_seq->rx.last[rkh_seq->rx.offsetidx];
988 msg_off = msg_seq - rkh_off;
989 if (msg_off > 0xC0000000)
990 goto out; /* too old message, drop it */
991
992 if (msg_off <= 0x40000000) {
993 for (i = 0; i < rkh_seq->rx.num_last; i++) {
994 if (rkh_seq->rx.last[i] == msg_seq)
995 goto out; /* duplicate message, drop it */
996 }
997
998 return FT_RRB_SEQ_OK;
999 }
1000
1001defer:
1002 if (no_defer)
1003 goto out;
1004
1005 wpa_printf(MSG_DEBUG, "FT: Possibly invalid sequence number in %s from "
1006 MACSTR, msgtype, MAC2STR(src_addr));
1007
1008 return FT_RRB_SEQ_DEFER;
1009out:
1010 wpa_printf(MSG_DEBUG, "FT: Invalid sequence number in %s from " MACSTR,
1011 msgtype, MAC2STR(src_addr));
1012
1013 return FT_RRB_SEQ_DROP;
1014}
1015
1016
1017static void
1018wpa_ft_rrb_seq_accept(struct wpa_authenticator *wpa_auth,
1019 struct ft_remote_seq *rkh_seq, const u8 *src_addr,
1020 const u8 *auth, size_t auth_len,
1021 const char *msgtype)
1022{
1023 const u8 *f_seq;
1024 size_t f_seq_len;
1025 const struct ft_rrb_seq *msg_both;
1026 u32 msg_seq, msg_off, min_off, rkh_off;
1027 int minidx = 0;
1028 unsigned int i;
1029
1030 RRB_GET_AUTH(FT_RRB_SEQ, seq, msgtype, sizeof(*msg_both));
1031 msg_both = (const struct ft_rrb_seq *) f_seq;
1032
1033 msg_seq = le_to_host32(msg_both->seq);
1034
1035 if (rkh_seq->rx.num_last < FT_REMOTE_SEQ_BACKLOG) {
1036 rkh_seq->rx.last[rkh_seq->rx.num_last] = msg_seq;
1037 rkh_seq->rx.num_last++;
1038 return;
1039 }
1040
1041 rkh_off = rkh_seq->rx.last[rkh_seq->rx.offsetidx];
1042 for (i = 0; i < rkh_seq->rx.num_last; i++) {
1043 msg_off = rkh_seq->rx.last[i] - rkh_off;
1044 min_off = rkh_seq->rx.last[minidx] - rkh_off;
1045 if (msg_off < min_off && i != rkh_seq->rx.offsetidx)
1046 minidx = i;
1047 }
1048 rkh_seq->rx.last[rkh_seq->rx.offsetidx] = msg_seq;
1049 rkh_seq->rx.offsetidx = minidx;
1050
1051 return;
1052out:
1053 /* RRB_GET_AUTH should never fail here as
1054 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1055 wpa_printf(MSG_ERROR, "FT: %s() failed", __func__);
1056}
1057
1058
1059static int wpa_ft_new_seq(struct ft_remote_seq *rkh_seq,
1060 struct ft_rrb_seq *f_seq)
1061{
1062 struct os_reltime now;
1063
1064 if (os_get_reltime(&now) < 0)
1065 return -1;
1066
1067 if (!rkh_seq->tx.dom) {
1068 if (random_get_bytes((u8 *) &rkh_seq->tx.seq,
1069 sizeof(rkh_seq->tx.seq))) {
1070 wpa_printf(MSG_ERROR,
1071 "FT: Failed to get random data for sequence number initialization");
1072 rkh_seq->tx.seq = now.usec;
1073 }
1074 if (random_get_bytes((u8 *) &rkh_seq->tx.dom,
1075 sizeof(rkh_seq->tx.dom))) {
1076 wpa_printf(MSG_ERROR,
1077 "FT: Failed to get random data for sequence number initialization");
1078 rkh_seq->tx.dom = now.usec;
1079 }
1080 rkh_seq->tx.dom |= 1;
1081 }
1082
1083 f_seq->dom = host_to_le32(rkh_seq->tx.dom);
1084 f_seq->seq = host_to_le32(rkh_seq->tx.seq);
1085 f_seq->ts = host_to_le32(now.sec);
1086
1087 rkh_seq->tx.seq++;
1088
1089 return 0;
1090}
1091
1092
6fc6879b 1093struct wpa_ft_pmk_r0_sa {
09211c98 1094 struct dl_list list;
a3e18dbb
JM
1095 u8 pmk_r0[PMK_LEN_MAX];
1096 size_t pmk_r0_len;
6fc6879b
JM
1097 u8 pmk_r0_name[WPA_PMK_NAME_LEN];
1098 u8 spa[ETH_ALEN];
1b484d60 1099 int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */
17010c38 1100 struct vlan_description *vlan;
3a3e2832 1101 os_time_t expiration; /* 0 for no expiration */
069b4e30
MB
1102 u8 *identity;
1103 size_t identity_len;
1104 u8 *radius_cui;
1105 size_t radius_cui_len;
a6509e85
MB
1106 os_time_t session_timeout; /* 0 for no expiration */
1107 /* TODO: radius_class, EAP type */
6fc6879b
JM
1108 int pmk_r1_pushed;
1109};
1110
1111struct wpa_ft_pmk_r1_sa {
09211c98 1112 struct dl_list list;
a3e18dbb
JM
1113 u8 pmk_r1[PMK_LEN_MAX];
1114 size_t pmk_r1_len;
6fc6879b
JM
1115 u8 pmk_r1_name[WPA_PMK_NAME_LEN];
1116 u8 spa[ETH_ALEN];
1b484d60 1117 int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */
17010c38 1118 struct vlan_description *vlan;
069b4e30
MB
1119 u8 *identity;
1120 size_t identity_len;
1121 u8 *radius_cui;
1122 size_t radius_cui_len;
a6509e85
MB
1123 os_time_t session_timeout; /* 0 for no expiration */
1124 /* TODO: radius_class, EAP type */
6fc6879b
JM
1125};
1126
1127struct wpa_ft_pmk_cache {
09211c98
MB
1128 struct dl_list pmk_r0; /* struct wpa_ft_pmk_r0_sa */
1129 struct dl_list pmk_r1; /* struct wpa_ft_pmk_r1_sa */
6fc6879b
JM
1130};
1131
09211c98 1132
3a3e2832
MB
1133static void wpa_ft_expire_pmk_r0(void *eloop_ctx, void *timeout_ctx);
1134static void wpa_ft_expire_pmk_r1(void *eloop_ctx, void *timeout_ctx);
1135
1136
09211c98
MB
1137static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa *r0)
1138{
1139 if (!r0)
1140 return;
1141
1142 dl_list_del(&r0->list);
3a3e2832 1143 eloop_cancel_timeout(wpa_ft_expire_pmk_r0, r0, NULL);
09211c98 1144
a3e18dbb 1145 os_memset(r0->pmk_r0, 0, PMK_LEN_MAX);
17010c38 1146 os_free(r0->vlan);
069b4e30
MB
1147 os_free(r0->identity);
1148 os_free(r0->radius_cui);
09211c98
MB
1149 os_free(r0);
1150}
1151
1152
3a3e2832
MB
1153static void wpa_ft_expire_pmk_r0(void *eloop_ctx, void *timeout_ctx)
1154{
1155 struct wpa_ft_pmk_r0_sa *r0 = eloop_ctx;
1156 struct os_reltime now;
1157 int expires_in;
a6509e85 1158 int session_timeout;
3a3e2832
MB
1159
1160 os_get_reltime(&now);
1161
1162 if (!r0)
1163 return;
1164
1165 expires_in = r0->expiration - now.sec;
a6509e85
MB
1166 session_timeout = r0->session_timeout - now.sec;
1167 /* conditions to remove from cache:
1168 * a) r0->expiration is set and hit
1169 * -or-
1170 * b) r0->session_timeout is set and hit
1171 */
1172 if ((!r0->expiration || expires_in > 0) &&
1173 (!r0->session_timeout || session_timeout > 0)) {
3a3e2832 1174 wpa_printf(MSG_ERROR,
a6509e85
MB
1175 "FT: %s() called for non-expired entry %p",
1176 __func__, r0);
3a3e2832 1177 eloop_cancel_timeout(wpa_ft_expire_pmk_r0, r0, NULL);
a6509e85
MB
1178 if (r0->expiration && expires_in > 0)
1179 eloop_register_timeout(expires_in + 1, 0,
1180 wpa_ft_expire_pmk_r0, r0, NULL);
1181 if (r0->session_timeout && session_timeout > 0)
1182 eloop_register_timeout(session_timeout + 1, 0,
1183 wpa_ft_expire_pmk_r0, r0, NULL);
3a3e2832
MB
1184 return;
1185 }
1186
1187 wpa_ft_free_pmk_r0(r0);
1188}
1189
1190
09211c98
MB
1191static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa *r1)
1192{
1193 if (!r1)
1194 return;
1195
1196 dl_list_del(&r1->list);
3a3e2832 1197 eloop_cancel_timeout(wpa_ft_expire_pmk_r1, r1, NULL);
09211c98 1198
a3e18dbb 1199 os_memset(r1->pmk_r1, 0, PMK_LEN_MAX);
17010c38 1200 os_free(r1->vlan);
069b4e30
MB
1201 os_free(r1->identity);
1202 os_free(r1->radius_cui);
09211c98
MB
1203 os_free(r1);
1204}
1205
1206
3a3e2832
MB
1207static void wpa_ft_expire_pmk_r1(void *eloop_ctx, void *timeout_ctx)
1208{
1209 struct wpa_ft_pmk_r1_sa *r1 = eloop_ctx;
1210
1211 wpa_ft_free_pmk_r1(r1);
1212}
1213
1214
6fc6879b
JM
1215struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void)
1216{
1217 struct wpa_ft_pmk_cache *cache;
1218
1219 cache = os_zalloc(sizeof(*cache));
09211c98
MB
1220 if (cache) {
1221 dl_list_init(&cache->pmk_r0);
1222 dl_list_init(&cache->pmk_r1);
1223 }
6fc6879b
JM
1224
1225 return cache;
1226}
1227
1228
1229void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache)
1230{
1231 struct wpa_ft_pmk_r0_sa *r0, *r0prev;
1232 struct wpa_ft_pmk_r1_sa *r1, *r1prev;
1233
09211c98
MB
1234 dl_list_for_each_safe(r0, r0prev, &cache->pmk_r0,
1235 struct wpa_ft_pmk_r0_sa, list)
1236 wpa_ft_free_pmk_r0(r0);
6fc6879b 1237
09211c98
MB
1238 dl_list_for_each_safe(r1, r1prev, &cache->pmk_r1,
1239 struct wpa_ft_pmk_r1_sa, list)
1240 wpa_ft_free_pmk_r1(r1);
6fc6879b
JM
1241
1242 os_free(cache);
1243}
1244
1245
89dea17e
MB
1246static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth,
1247 const u8 *spa, const u8 *pmk_r0,
a3e18dbb 1248 size_t pmk_r0_len,
3a3e2832 1249 const u8 *pmk_r0_name, int pairwise,
17010c38 1250 const struct vlan_description *vlan,
a6509e85 1251 int expires_in, int session_timeout,
069b4e30
MB
1252 const u8 *identity, size_t identity_len,
1253 const u8 *radius_cui, size_t radius_cui_len)
6fc6879b
JM
1254{
1255 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
1256 struct wpa_ft_pmk_r0_sa *r0;
3a3e2832 1257 struct os_reltime now;
6fc6879b 1258
3a3e2832
MB
1259 /* TODO: add limit on number of entries in cache */
1260 os_get_reltime(&now);
6fc6879b
JM
1261
1262 r0 = os_zalloc(sizeof(*r0));
1263 if (r0 == NULL)
1264 return -1;
1265
a3e18dbb
JM
1266 os_memcpy(r0->pmk_r0, pmk_r0, pmk_r0_len);
1267 r0->pmk_r0_len = pmk_r0_len;
6fc6879b
JM
1268 os_memcpy(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
1269 os_memcpy(r0->spa, spa, ETH_ALEN);
1b484d60 1270 r0->pairwise = pairwise;
3a3e2832
MB
1271 if (expires_in > 0)
1272 r0->expiration = now.sec + expires_in;
17010c38
MB
1273 if (vlan && vlan->notempty) {
1274 r0->vlan = os_zalloc(sizeof(*vlan));
1275 if (!r0->vlan) {
1276 bin_clear_free(r0, sizeof(*r0));
1277 return -1;
1278 }
1279 *r0->vlan = *vlan;
1280 }
069b4e30
MB
1281 if (identity) {
1282 r0->identity = os_malloc(identity_len);
1283 if (r0->identity) {
1284 os_memcpy(r0->identity, identity, identity_len);
1285 r0->identity_len = identity_len;
1286 }
1287 }
1288 if (radius_cui) {
1289 r0->radius_cui = os_malloc(radius_cui_len);
1290 if (r0->radius_cui) {
1291 os_memcpy(r0->radius_cui, radius_cui, radius_cui_len);
1292 r0->radius_cui_len = radius_cui_len;
1293 }
1294 }
a6509e85
MB
1295 if (session_timeout > 0)
1296 r0->session_timeout = now.sec + session_timeout;
6fc6879b 1297
09211c98 1298 dl_list_add(&cache->pmk_r0, &r0->list);
3a3e2832
MB
1299 if (expires_in > 0)
1300 eloop_register_timeout(expires_in + 1, 0, wpa_ft_expire_pmk_r0,
1301 r0, NULL);
a6509e85
MB
1302 if (session_timeout > 0)
1303 eloop_register_timeout(session_timeout + 1, 0,
1304 wpa_ft_expire_pmk_r0, r0, NULL);
6fc6879b
JM
1305
1306 return 0;
1307}
1308
1309
1310static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth,
1311 const u8 *spa, const u8 *pmk_r0_name,
245fc96e 1312 const struct wpa_ft_pmk_r0_sa **r0_out)
6fc6879b
JM
1313{
1314 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
1315 struct wpa_ft_pmk_r0_sa *r0;
3a3e2832 1316 struct os_reltime now;
6fc6879b 1317
3a3e2832 1318 os_get_reltime(&now);
09211c98 1319 dl_list_for_each(r0, &cache->pmk_r0, struct wpa_ft_pmk_r0_sa, list) {
6fc6879b 1320 if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 &&
870834a1
JM
1321 os_memcmp_const(r0->pmk_r0_name, pmk_r0_name,
1322 WPA_PMK_NAME_LEN) == 0) {
245fc96e 1323 *r0_out = r0;
6fc6879b
JM
1324 return 0;
1325 }
6fc6879b
JM
1326 }
1327
245fc96e 1328 *r0_out = NULL;
6fc6879b
JM
1329 return -1;
1330}
1331
1332
1333static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth,
1334 const u8 *spa, const u8 *pmk_r1,
a3e18dbb 1335 size_t pmk_r1_len,
3a3e2832 1336 const u8 *pmk_r1_name, int pairwise,
17010c38 1337 const struct vlan_description *vlan,
a6509e85 1338 int expires_in, int session_timeout,
069b4e30
MB
1339 const u8 *identity, size_t identity_len,
1340 const u8 *radius_cui, size_t radius_cui_len)
6fc6879b
JM
1341{
1342 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
3a3e2832 1343 int max_expires_in = wpa_auth->conf.r1_max_key_lifetime;
6fc6879b 1344 struct wpa_ft_pmk_r1_sa *r1;
a6509e85 1345 struct os_reltime now;
6fc6879b 1346
3a3e2832 1347 /* TODO: limit on number of entries in cache */
a6509e85 1348 os_get_reltime(&now);
3a3e2832
MB
1349
1350 if (max_expires_in && (max_expires_in < expires_in || expires_in == 0))
1351 expires_in = max_expires_in;
6fc6879b
JM
1352
1353 r1 = os_zalloc(sizeof(*r1));
1354 if (r1 == NULL)
1355 return -1;
1356
a3e18dbb
JM
1357 os_memcpy(r1->pmk_r1, pmk_r1, pmk_r1_len);
1358 r1->pmk_r1_len = pmk_r1_len;
6fc6879b
JM
1359 os_memcpy(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
1360 os_memcpy(r1->spa, spa, ETH_ALEN);
1b484d60 1361 r1->pairwise = pairwise;
17010c38
MB
1362 if (vlan && vlan->notempty) {
1363 r1->vlan = os_zalloc(sizeof(*vlan));
1364 if (!r1->vlan) {
1365 bin_clear_free(r1, sizeof(*r1));
1366 return -1;
1367 }
1368 *r1->vlan = *vlan;
1369 }
069b4e30
MB
1370 if (identity) {
1371 r1->identity = os_malloc(identity_len);
1372 if (r1->identity) {
1373 os_memcpy(r1->identity, identity, identity_len);
1374 r1->identity_len = identity_len;
1375 }
1376 }
1377 if (radius_cui) {
1378 r1->radius_cui = os_malloc(radius_cui_len);
1379 if (r1->radius_cui) {
1380 os_memcpy(r1->radius_cui, radius_cui, radius_cui_len);
1381 r1->radius_cui_len = radius_cui_len;
1382 }
1383 }
a6509e85
MB
1384 if (session_timeout > 0)
1385 r1->session_timeout = now.sec + session_timeout;
6fc6879b 1386
09211c98 1387 dl_list_add(&cache->pmk_r1, &r1->list);
6fc6879b 1388
3a3e2832
MB
1389 if (expires_in > 0)
1390 eloop_register_timeout(expires_in + 1, 0, wpa_ft_expire_pmk_r1,
1391 r1, NULL);
a6509e85
MB
1392 if (session_timeout > 0)
1393 eloop_register_timeout(session_timeout + 1, 0,
1394 wpa_ft_expire_pmk_r1, r1, NULL);
3a3e2832 1395
6fc6879b
JM
1396 return 0;
1397}
1398
1399
1400static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
1401 const u8 *spa, const u8 *pmk_r1_name,
a3e18dbb 1402 u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
069b4e30
MB
1403 struct vlan_description *vlan,
1404 const u8 **identity, size_t *identity_len,
a6509e85
MB
1405 const u8 **radius_cui, size_t *radius_cui_len,
1406 int *session_timeout)
6fc6879b
JM
1407{
1408 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
1409 struct wpa_ft_pmk_r1_sa *r1;
a6509e85
MB
1410 struct os_reltime now;
1411
1412 os_get_reltime(&now);
6fc6879b 1413
09211c98 1414 dl_list_for_each(r1, &cache->pmk_r1, struct wpa_ft_pmk_r1_sa, list) {
6fc6879b 1415 if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 &&
870834a1
JM
1416 os_memcmp_const(r1->pmk_r1_name, pmk_r1_name,
1417 WPA_PMK_NAME_LEN) == 0) {
a3e18dbb
JM
1418 os_memcpy(pmk_r1, r1->pmk_r1, r1->pmk_r1_len);
1419 *pmk_r1_len = r1->pmk_r1_len;
1b484d60
JM
1420 if (pairwise)
1421 *pairwise = r1->pairwise;
17010c38
MB
1422 if (vlan && r1->vlan)
1423 *vlan = *r1->vlan;
1424 if (vlan && !r1->vlan)
1425 os_memset(vlan, 0, sizeof(*vlan));
069b4e30
MB
1426 if (identity && identity_len) {
1427 *identity = r1->identity;
1428 *identity_len = r1->identity_len;
1429 }
1430 if (radius_cui && radius_cui_len) {
1431 *radius_cui = r1->radius_cui;
1432 *radius_cui_len = r1->radius_cui_len;
1433 }
a6509e85
MB
1434 if (session_timeout && r1->session_timeout > now.sec)
1435 *session_timeout = r1->session_timeout -
1436 now.sec;
1437 else if (session_timeout && r1->session_timeout)
1438 *session_timeout = 1;
1439 else
1440 *session_timeout = 0;
6fc6879b
JM
1441 return 0;
1442 }
6fc6879b
JM
1443 }
1444
1445 return -1;
1446}
1447
1448
eefe8630
MB
1449static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh *r0kh)
1450{
1451 if (r0kh->seq)
1452 return 0;
1453
1454 r0kh->seq = os_zalloc(sizeof(*r0kh->seq));
1455 if (!r0kh->seq) {
1456 wpa_printf(MSG_DEBUG, "FT: Failed to allocate r0kh->seq");
1457 return -1;
1458 }
1459
1460 dl_list_init(&r0kh->seq->rx.queue);
1461
1462 return 0;
1463}
1464
1465
245fc96e 1466static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator *wpa_auth,
eefe8630 1467 const u8 *f_r0kh_id, size_t f_r0kh_id_len,
3a46cf93
MB
1468 struct ft_remote_r0kh **r0kh_out,
1469 struct ft_remote_r0kh **r0kh_wildcard)
245fc96e
MB
1470{
1471 struct ft_remote_r0kh *r0kh;
1472
3a46cf93 1473 *r0kh_wildcard = NULL;
eefe8630
MB
1474 *r0kh_out = NULL;
1475
3a46cf93
MB
1476 if (wpa_auth->conf.r0kh_list)
1477 r0kh = *wpa_auth->conf.r0kh_list;
1478 else
1479 r0kh = NULL;
1480 for (; r0kh; r0kh = r0kh->next) {
1481 if (r0kh->id_len == 1 && r0kh->id[0] == '*')
1482 *r0kh_wildcard = r0kh;
eefe8630 1483 if (f_r0kh_id && r0kh->id_len == f_r0kh_id_len &&
3a46cf93 1484 os_memcmp_const(f_r0kh_id, r0kh->id, f_r0kh_id_len) == 0)
eefe8630 1485 *r0kh_out = r0kh;
245fc96e
MB
1486 }
1487
3a46cf93 1488 if (!*r0kh_out && !*r0kh_wildcard)
245fc96e
MB
1489 wpa_printf(MSG_DEBUG, "FT: No matching R0KH found");
1490
eefe8630
MB
1491 if (*r0kh_out && wpa_ft_rrb_init_r0kh_seq(*r0kh_out) < 0)
1492 *r0kh_out = NULL;
1493}
1494
1495
1496static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh *r1kh)
1497{
1498 if (r1kh->seq)
1499 return 0;
1500
1501 r1kh->seq = os_zalloc(sizeof(*r1kh->seq));
1502 if (!r1kh->seq) {
1503 wpa_printf(MSG_DEBUG, "FT: Failed to allocate r1kh->seq");
1504 return -1;
1505 }
1506
1507 dl_list_init(&r1kh->seq->rx.queue);
1508
1509 return 0;
245fc96e
MB
1510}
1511
1512
1513static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator *wpa_auth,
eefe8630 1514 const u8 *f_r1kh_id,
3a46cf93
MB
1515 struct ft_remote_r1kh **r1kh_out,
1516 struct ft_remote_r1kh **r1kh_wildcard)
245fc96e
MB
1517{
1518 struct ft_remote_r1kh *r1kh;
1519
3a46cf93 1520 *r1kh_wildcard = NULL;
eefe8630
MB
1521 *r1kh_out = NULL;
1522
3a46cf93
MB
1523 if (wpa_auth->conf.r1kh_list)
1524 r1kh = *wpa_auth->conf.r1kh_list;
1525 else
1526 r1kh = NULL;
1527 for (; r1kh; r1kh = r1kh->next) {
1528 if (is_zero_ether_addr(r1kh->addr) &&
1529 is_zero_ether_addr(r1kh->id))
1530 *r1kh_wildcard = r1kh;
245fc96e 1531 if (f_r1kh_id &&
3a46cf93 1532 os_memcmp_const(r1kh->id, f_r1kh_id, FT_R1KH_ID_LEN) == 0)
eefe8630 1533 *r1kh_out = r1kh;
245fc96e
MB
1534 }
1535
3a46cf93 1536 if (!*r1kh_out && !*r1kh_wildcard)
245fc96e
MB
1537 wpa_printf(MSG_DEBUG, "FT: No matching R1KH found");
1538
eefe8630
MB
1539 if (*r1kh_out && wpa_ft_rrb_init_r1kh_seq(*r1kh_out) < 0)
1540 *r1kh_out = NULL;
245fc96e
MB
1541}
1542
1543
1544static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator *wpa_auth,
1545 const u8 *f_r0kh_id, size_t f_r0kh_id_len)
1546{
1547 if (f_r0kh_id_len != wpa_auth->conf.r0_key_holder_len ||
1548 os_memcmp_const(f_r0kh_id, wpa_auth->conf.r0_key_holder,
1549 f_r0kh_id_len) != 0)
1550 return -1;
1551
1552 return 0;
1553}
1554
1555
1556static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator *wpa_auth,
1557 const u8 *f_r1kh_id)
1558{
1559 if (os_memcmp_const(f_r1kh_id, wpa_auth->conf.r1_key_holder,
1560 FT_R1KH_ID_LEN) != 0)
1561 return -1;
1562
1563 return 0;
1564}
1565
1566
3a46cf93
MB
1567static void wpa_ft_rrb_del_r0kh(void *eloop_ctx, void *timeout_ctx)
1568{
1569 struct wpa_authenticator *wpa_auth = eloop_ctx;
1570 struct ft_remote_r0kh *r0kh, *prev = NULL;
1571
1572 if (!wpa_auth->conf.r0kh_list)
1573 return;
1574
1575 for (r0kh = *wpa_auth->conf.r0kh_list; r0kh; r0kh = r0kh->next) {
1576 if (r0kh == timeout_ctx)
1577 break;
1578 prev = r0kh;
1579 }
1580 if (!r0kh)
1581 return;
1582 if (prev)
1583 prev->next = r0kh->next;
1584 else
1585 *wpa_auth->conf.r0kh_list = r0kh->next;
1586 if (r0kh->seq)
1587 wpa_ft_rrb_seq_flush(wpa_auth, r0kh->seq, 0);
1588 os_free(r0kh->seq);
1589 os_free(r0kh);
1590}
1591
1592
1593static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator *wpa_auth,
1594 struct ft_remote_r0kh *r0kh, int timeout)
1595{
1596 if (timeout > 0)
1597 eloop_replenish_timeout(timeout, 0, wpa_ft_rrb_del_r0kh,
1598 wpa_auth, r0kh);
1599}
1600
1601
1602static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator *wpa_auth,
1603 struct ft_remote_r0kh *r0kh, int timeout)
1604{
1605 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh, wpa_auth, r0kh);
1606
1607 if (timeout > 0)
1608 eloop_register_timeout(timeout, 0, wpa_ft_rrb_del_r0kh,
1609 wpa_auth, r0kh);
1610}
1611
1612
1613static struct ft_remote_r0kh *
1614wpa_ft_rrb_add_r0kh(struct wpa_authenticator *wpa_auth,
1615 struct ft_remote_r0kh *r0kh_wildcard,
1616 const u8 *src_addr, const u8 *r0kh_id, size_t id_len,
1617 int timeout)
1618{
1619 struct ft_remote_r0kh *r0kh;
1620
1621 if (!wpa_auth->conf.r0kh_list)
1622 return NULL;
1623
1624 r0kh = os_zalloc(sizeof(*r0kh));
1625 if (!r0kh)
1626 return NULL;
1627
1628 if (src_addr)
1629 os_memcpy(r0kh->addr, src_addr, sizeof(r0kh->addr));
1630
1631 if (id_len > FT_R0KH_ID_MAX_LEN)
1632 id_len = FT_R0KH_ID_MAX_LEN;
1633 os_memcpy(r0kh->id, r0kh_id, id_len);
1634 r0kh->id_len = id_len;
1635
1636 os_memcpy(r0kh->key, r0kh_wildcard->key, sizeof(r0kh->key));
1637
1638 r0kh->next = *wpa_auth->conf.r0kh_list;
1639 *wpa_auth->conf.r0kh_list = r0kh;
1640
1641 if (timeout > 0)
1642 eloop_register_timeout(timeout, 0, wpa_ft_rrb_del_r0kh,
1643 wpa_auth, r0kh);
1644
1645 if (wpa_ft_rrb_init_r0kh_seq(r0kh) < 0)
1646 return NULL;
1647
1648 return r0kh;
1649}
1650
1651
1652static void wpa_ft_rrb_del_r1kh(void *eloop_ctx, void *timeout_ctx)
1653{
1654 struct wpa_authenticator *wpa_auth = eloop_ctx;
1655 struct ft_remote_r1kh *r1kh, *prev = NULL;
1656
1657 if (!wpa_auth->conf.r1kh_list)
1658 return;
1659
1660 for (r1kh = *wpa_auth->conf.r1kh_list; r1kh; r1kh = r1kh->next) {
1661 if (r1kh == timeout_ctx)
1662 break;
1663 prev = r1kh;
1664 }
1665 if (!r1kh)
1666 return;
1667 if (prev)
1668 prev->next = r1kh->next;
1669 else
1670 *wpa_auth->conf.r1kh_list = r1kh->next;
1671 if (r1kh->seq)
1672 wpa_ft_rrb_seq_flush(wpa_auth, r1kh->seq, 0);
1673 os_free(r1kh->seq);
1674 os_free(r1kh);
1675}
1676
1677
1678static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator *wpa_auth,
1679 struct ft_remote_r1kh *r1kh, int timeout)
1680{
1681 if (timeout > 0)
1682 eloop_replenish_timeout(timeout, 0, wpa_ft_rrb_del_r1kh,
1683 wpa_auth, r1kh);
1684}
1685
1686
1687static struct ft_remote_r1kh *
1688wpa_ft_rrb_add_r1kh(struct wpa_authenticator *wpa_auth,
1689 struct ft_remote_r1kh *r1kh_wildcard,
1690 const u8 *src_addr, const u8 *r1kh_id, int timeout)
1691{
1692 struct ft_remote_r1kh *r1kh;
1693
1694 if (!wpa_auth->conf.r1kh_list)
1695 return NULL;
1696
1697 r1kh = os_zalloc(sizeof(*r1kh));
1698 if (!r1kh)
1699 return NULL;
1700
1701 os_memcpy(r1kh->addr, src_addr, sizeof(r1kh->addr));
1702 os_memcpy(r1kh->id, r1kh_id, sizeof(r1kh->id));
1703 os_memcpy(r1kh->key, r1kh_wildcard->key, sizeof(r1kh->key));
1704 r1kh->next = *wpa_auth->conf.r1kh_list;
1705 *wpa_auth->conf.r1kh_list = r1kh;
1706
1707 if (timeout > 0)
1708 eloop_register_timeout(timeout, 0, wpa_ft_rrb_del_r1kh,
1709 wpa_auth, r1kh);
1710
1711 if (wpa_ft_rrb_init_r1kh_seq(r1kh) < 0)
1712 return NULL;
1713
1714 return r1kh;
1715}
1716
1717
1718void wpa_ft_sta_deinit(struct wpa_state_machine *sm)
1719{
1720 eloop_cancel_timeout(wpa_ft_expire_pull, sm, NULL);
1721}
1722
1723
eefe8630
MB
1724static void wpa_ft_deinit_seq(struct wpa_authenticator *wpa_auth)
1725{
1726 struct ft_remote_r0kh *r0kh;
1727 struct ft_remote_r1kh *r1kh;
1728
1729 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout, wpa_auth, ELOOP_ALL_CTX);
1730
3a46cf93
MB
1731 if (wpa_auth->conf.r0kh_list)
1732 r0kh = *wpa_auth->conf.r0kh_list;
1733 else
1734 r0kh = NULL;
1735 for (; r0kh; r0kh = r0kh->next) {
eefe8630
MB
1736 if (!r0kh->seq)
1737 continue;
1738 wpa_ft_rrb_seq_flush(wpa_auth, r0kh->seq, 0);
1739 os_free(r0kh->seq);
1740 r0kh->seq = NULL;
1741 }
1742
3a46cf93
MB
1743 if (wpa_auth->conf.r1kh_list)
1744 r1kh = *wpa_auth->conf.r1kh_list;
1745 else
1746 r1kh = NULL;
1747 for (; r1kh; r1kh = r1kh->next) {
eefe8630
MB
1748 if (!r1kh->seq)
1749 continue;
1750 wpa_ft_rrb_seq_flush(wpa_auth, r1kh->seq, 0);
1751 os_free(r1kh->seq);
1752 r1kh->seq = NULL;
1753 }
1754}
1755
1756
3a46cf93
MB
1757static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator *wpa_auth)
1758{
1759 struct ft_remote_r0kh *r0kh, *r0kh_next, *r0kh_prev = NULL;
1760 struct ft_remote_r1kh *r1kh, *r1kh_next, *r1kh_prev = NULL;
1761
1762 if (wpa_auth->conf.r0kh_list)
1763 r0kh = *wpa_auth->conf.r0kh_list;
1764 else
1765 r0kh = NULL;
1766 while (r0kh) {
1767 r0kh_next = r0kh->next;
1768 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh, wpa_auth,
1769 r0kh) > 0) {
1770 if (r0kh_prev)
1771 r0kh_prev->next = r0kh_next;
1772 else
1773 *wpa_auth->conf.r0kh_list = r0kh_next;
1774 os_free(r0kh);
1775 } else {
1776 r0kh_prev = r0kh;
1777 }
1778 r0kh = r0kh_next;
1779 }
1780
1781 if (wpa_auth->conf.r1kh_list)
1782 r1kh = *wpa_auth->conf.r1kh_list;
1783 else
1784 r1kh = NULL;
1785 while (r1kh) {
1786 r1kh_next = r1kh->next;
1787 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh, wpa_auth,
1788 r1kh) > 0) {
1789 if (r1kh_prev)
1790 r1kh_prev->next = r1kh_next;
1791 else
1792 *wpa_auth->conf.r1kh_list = r1kh_next;
1793 os_free(r1kh);
1794 } else {
1795 r1kh_prev = r1kh;
1796 }
1797 r1kh = r1kh_next;
1798 }
1799}
1800
1801
eefe8630
MB
1802void wpa_ft_deinit(struct wpa_authenticator *wpa_auth)
1803{
1804 wpa_ft_deinit_seq(wpa_auth);
3a46cf93
MB
1805 wpa_ft_deinit_rkh_tmp(wpa_auth);
1806}
1807
1808
1809static void wpa_ft_block_r0kh(struct wpa_authenticator *wpa_auth,
1810 const u8 *f_r0kh_id, size_t f_r0kh_id_len)
1811{
1812 struct ft_remote_r0kh *r0kh, *r0kh_wildcard;
1813
1814 if (!wpa_auth->conf.rkh_neg_timeout)
1815 return;
1816
1817 wpa_ft_rrb_lookup_r0kh(wpa_auth, f_r0kh_id, f_r0kh_id_len,
1818 &r0kh, &r0kh_wildcard);
1819
1820 if (!r0kh_wildcard) {
1821 /* r0kh removed after neg_timeout and might need re-adding */
1822 return;
1823 }
1824
1825 wpa_hexdump(MSG_DEBUG, "FT: Blacklist R0KH-ID",
1826 f_r0kh_id, f_r0kh_id_len);
1827
1828 if (r0kh) {
1829 wpa_ft_rrb_r0kh_timeout(wpa_auth, r0kh,
1830 wpa_auth->conf.rkh_neg_timeout);
1831 os_memset(r0kh->addr, 0, ETH_ALEN);
1832 } else
1833 wpa_ft_rrb_add_r0kh(wpa_auth, r0kh_wildcard, NULL, f_r0kh_id,
1834 f_r0kh_id_len,
1835 wpa_auth->conf.rkh_neg_timeout);
1836}
1837
1838
1839static void wpa_ft_expire_pull(void *eloop_ctx, void *timeout_ctx)
1840{
1841 struct wpa_state_machine *sm = eloop_ctx;
1842
1843 wpa_printf(MSG_DEBUG, "FT: Timeout pending pull request for " MACSTR,
1844 MAC2STR(sm->addr));
1845 if (sm->ft_pending_pull_left_retries <= 0)
1846 wpa_ft_block_r0kh(sm->wpa_auth, sm->r0kh_id, sm->r0kh_id_len);
1847
1848 /* cancel multiple timeouts */
1849 eloop_cancel_timeout(wpa_ft_expire_pull, sm, NULL);
1850 ft_finish_pull(sm);
eefe8630
MB
1851}
1852
1853
692ec305
JM
1854static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm,
1855 const u8 *ies, size_t ies_len,
1856 const u8 *pmk_r0_name)
6fc6879b 1857{
3a46cf93 1858 struct ft_remote_r0kh *r0kh, *r0kh_wildcard;
245fc96e 1859 u8 *packet = NULL;
eefe8630 1860 const u8 *key, *f_r1kh_id = sm->wpa_auth->conf.r1_key_holder;
245fc96e 1861 size_t packet_len, key_len;
eefe8630 1862 struct ft_rrb_seq f_seq;
3a46cf93
MB
1863 int tsecs, tusecs, first;
1864 struct wpabuf *ft_pending_req_ies;
1865 int r0kh_timeout;
245fc96e
MB
1866 struct tlv_list req_enc[] = {
1867 { .type = FT_RRB_PMK_R0_NAME, .len = WPA_PMK_NAME_LEN,
1868 .data = pmk_r0_name },
1869 { .type = FT_RRB_S1KH_ID, .len = ETH_ALEN,
1870 .data = sm->addr },
1871 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
1872 };
1873 struct tlv_list req_auth[] = {
1874 { .type = FT_RRB_NONCE, .len = FT_RRB_NONCE_LEN,
1875 .data = sm->ft_pending_pull_nonce },
eefe8630
MB
1876 { .type = FT_RRB_SEQ, .len = sizeof(f_seq),
1877 .data = (u8 *) &f_seq },
245fc96e
MB
1878 { .type = FT_RRB_R0KH_ID, .len = sm->r0kh_id_len,
1879 .data = sm->r0kh_id },
1880 { .type = FT_RRB_R1KH_ID, .len = FT_R1KH_ID_LEN,
eefe8630 1881 .data = f_r1kh_id },
245fc96e
MB
1882 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
1883 };
1884
3a46cf93
MB
1885 if (sm->ft_pending_pull_left_retries <= 0)
1886 return -1;
1887 first = sm->ft_pending_pull_left_retries ==
1888 sm->wpa_auth->conf.rkh_pull_retries;
1889 sm->ft_pending_pull_left_retries--;
1890
eefe8630 1891 wpa_ft_rrb_lookup_r0kh(sm->wpa_auth, sm->r0kh_id, sm->r0kh_id_len,
3a46cf93
MB
1892 &r0kh, &r0kh_wildcard);
1893
1894 /* Keep r0kh sufficiently long in the list for seq num check */
1895 r0kh_timeout = sm->wpa_auth->conf.rkh_pull_timeout / 1000 +
1896 1 + ftRRBseqTimeout;
1897 if (r0kh) {
1898 wpa_ft_rrb_r0kh_replenish(sm->wpa_auth, r0kh, r0kh_timeout);
1899 } else if (r0kh_wildcard) {
1900 wpa_printf(MSG_DEBUG, "FT: Using wildcard R0KH-ID");
1901 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1902 r0kh = wpa_ft_rrb_add_r0kh(sm->wpa_auth, r0kh_wildcard,
1903 r0kh_wildcard->addr,
1904 sm->r0kh_id, sm->r0kh_id_len,
1905 r0kh_timeout);
1906 }
692ec305
JM
1907 if (r0kh == NULL) {
1908 wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID",
1909 sm->r0kh_id, sm->r0kh_id_len);
6fc6879b 1910 return -1;
692ec305 1911 }
3a46cf93
MB
1912 if (is_zero_ether_addr(r0kh->addr)) {
1913 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID is blacklisted",
1914 sm->r0kh_id, sm->r0kh_id_len);
1915 return -1;
1916 }
1dc0945c
JM
1917 if (os_memcmp(r0kh->addr, sm->wpa_auth->addr, ETH_ALEN) == 0) {
1918 wpa_printf(MSG_DEBUG,
1919 "FT: R0KH-ID points to self - no matching key available");
1920 return -1;
1921 }
eefe8630 1922
245fc96e
MB
1923 key = r0kh->key;
1924 key_len = sizeof(r0kh->key);
6fc6879b
JM
1925
1926 wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
1927 "address " MACSTR, MAC2STR(r0kh->addr));
1928
eefe8630
MB
1929 if (r0kh->seq->rx.num_last == 0) {
1930 /* A sequence request will be sent out anyway when pull
1931 * response is received. Send it out now to avoid one RTT. */
1932 wpa_ft_rrb_seq_req(sm->wpa_auth, r0kh->seq, r0kh->addr,
1933 r0kh->id, r0kh->id_len, f_r1kh_id, key,
1934 key_len, NULL, 0, NULL, 0, NULL);
1935 }
1936
3a46cf93
MB
1937 if (first &&
1938 random_get_bytes(sm->ft_pending_pull_nonce, FT_RRB_NONCE_LEN) < 0) {
6fc6879b
JM
1939 wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
1940 "nonce");
1941 return -1;
1942 }
6fc6879b 1943
eefe8630
MB
1944 if (wpa_ft_new_seq(r0kh->seq, &f_seq) < 0) {
1945 wpa_printf(MSG_DEBUG, "FT: Failed to get seq num");
1946 return -1;
1947 }
1948
17010c38 1949 if (wpa_ft_rrb_build(key, key_len, req_enc, NULL, req_auth, NULL,
245fc96e
MB
1950 sm->wpa_auth->addr, FT_PACKET_R0KH_R1KH_PULL,
1951 &packet, &packet_len) < 0)
6fc6879b
JM
1952 return -1;
1953
3a46cf93 1954 ft_pending_req_ies = wpabuf_alloc_copy(ies, ies_len);
692ec305 1955 wpabuf_free(sm->ft_pending_req_ies);
3a46cf93 1956 sm->ft_pending_req_ies = ft_pending_req_ies;
245fc96e
MB
1957 if (!sm->ft_pending_req_ies) {
1958 os_free(packet);
692ec305 1959 return -1;
245fc96e 1960 }
692ec305 1961
3a46cf93
MB
1962 tsecs = sm->wpa_auth->conf.rkh_pull_timeout / 1000;
1963 tusecs = (sm->wpa_auth->conf.rkh_pull_timeout % 1000) * 1000;
1964 eloop_register_timeout(tsecs, tusecs, wpa_ft_expire_pull, sm, NULL);
1965
50bd8e0a 1966 wpa_ft_rrb_oui_send(sm->wpa_auth, r0kh->addr, FT_PACKET_R0KH_R1KH_PULL,
245fc96e
MB
1967 packet, packet_len);
1968
1969 os_free(packet);
6fc6879b
JM
1970
1971 return 0;
1972}
1973
1974
89dea17e
MB
1975int wpa_ft_store_pmk_fils(struct wpa_state_machine *sm,
1976 const u8 *pmk_r0, const u8 *pmk_r0_name)
1977{
3a3e2832 1978 int expires_in = sm->wpa_auth->conf.r0_key_lifetime;
17010c38 1979 struct vlan_description vlan;
069b4e30
MB
1980 const u8 *identity, *radius_cui;
1981 size_t identity_len, radius_cui_len;
a6509e85 1982 int session_timeout;
a3e18dbb 1983 size_t pmk_r0_len = PMK_LEN;
17010c38
MB
1984
1985 if (wpa_ft_get_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) {
1986 wpa_printf(MSG_DEBUG, "FT: vlan not available for STA " MACSTR,
1987 MAC2STR(sm->addr));
1988 return -1;
1989 }
3a3e2832 1990
069b4e30
MB
1991 identity_len = wpa_ft_get_identity(sm->wpa_auth, sm->addr, &identity);
1992 radius_cui_len = wpa_ft_get_radius_cui(sm->wpa_auth, sm->addr,
1993 &radius_cui);
a6509e85 1994 session_timeout = wpa_ft_get_session_timeout(sm->wpa_auth, sm->addr);
069b4e30 1995
a3e18dbb
JM
1996 return wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len,
1997 pmk_r0_name, sm->pairwise, &vlan, expires_in,
a6509e85
MB
1998 session_timeout, identity, identity_len,
1999 radius_cui, radius_cui_len);
89dea17e
MB
2000}
2001
2002
6fc6879b 2003int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
98cd3d1c 2004 struct wpa_ptk *ptk)
6fc6879b 2005{
a3e18dbb
JM
2006 u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN];
2007 size_t pmk_r0_len = PMK_LEN;
2008 size_t pmk_r1_len = pmk_r0_len;
2009 u8 pmk_r1[PMK_LEN_MAX];
6fc6879b
JM
2010 u8 ptk_name[WPA_PMK_NAME_LEN];
2011 const u8 *mdid = sm->wpa_auth->conf.mobility_domain;
2012 const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder;
2013 size_t r0kh_len = sm->wpa_auth->conf.r0_key_holder_len;
2014 const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder;
2015 const u8 *ssid = sm->wpa_auth->conf.ssid;
2016 size_t ssid_len = sm->wpa_auth->conf.ssid_len;
96590564 2017 int psk_local = sm->wpa_auth->conf.ft_psk_generate_local;
3a3e2832 2018 int expires_in = sm->wpa_auth->conf.r0_key_lifetime;
17010c38 2019 struct vlan_description vlan;
069b4e30
MB
2020 const u8 *identity, *radius_cui;
2021 size_t identity_len, radius_cui_len;
a6509e85 2022 int session_timeout;
6fc6879b 2023
6fc6879b
JM
2024 if (sm->xxkey_len == 0) {
2025 wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
2026 "derivation");
2027 return -1;
2028 }
2029
17010c38
MB
2030 if (wpa_ft_get_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) {
2031 wpa_printf(MSG_DEBUG, "FT: vlan not available for STA " MACSTR,
2032 MAC2STR(sm->addr));
2033 return -1;
2034 }
2035
069b4e30
MB
2036 identity_len = wpa_ft_get_identity(sm->wpa_auth, sm->addr, &identity);
2037 radius_cui_len = wpa_ft_get_radius_cui(sm->wpa_auth, sm->addr,
2038 &radius_cui);
a6509e85 2039 session_timeout = wpa_ft_get_session_timeout(sm->wpa_auth, sm->addr);
069b4e30 2040
364c064a
JM
2041 if (wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid,
2042 r0kh, r0kh_len, sm->addr,
2043 pmk_r0, pmk_r0_name) < 0)
2044 return -1;
a3e18dbb 2045 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len);
6fc6879b 2046 wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
96590564 2047 if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
a3e18dbb
JM
2048 wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len,
2049 pmk_r0_name,
a6509e85
MB
2050 sm->pairwise, &vlan, expires_in,
2051 session_timeout, identity, identity_len,
2052 radius_cui, radius_cui_len);
6fc6879b 2053
a3e18dbb 2054 if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr,
364c064a
JM
2055 pmk_r1, sm->pmk_r1_name) < 0)
2056 return -1;
a3e18dbb 2057 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len);
26e23750
JM
2058 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name,
2059 WPA_PMK_NAME_LEN);
96590564 2060 if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
a3e18dbb 2061 wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_len,
17010c38 2062 sm->pmk_r1_name, sm->pairwise, &vlan,
a6509e85
MB
2063 expires_in, session_timeout, identity,
2064 identity_len, radius_cui, radius_cui_len);
6fc6879b 2065
a3e18dbb
JM
2066 return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
2067 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name,
98cd3d1c 2068 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise);
6fc6879b
JM
2069}
2070
2071
2072static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
2073 const u8 *addr, int idx, u8 *seq)
2074{
cef8fac0 2075 if (wpa_auth->cb->get_seqnum == NULL)
6fc6879b 2076 return -1;
cef8fac0 2077 return wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
6fc6879b
JM
2078}
2079
2080
2081static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
2082{
2083 u8 *subelem;
2084 struct wpa_group *gsm = sm->group;
2085 size_t subelem_len, pad_len;
2086 const u8 *key;
2087 size_t key_len;
2088 u8 keybuf[32];
2089
2090 key_len = gsm->GTK_len;
2091 if (key_len > sizeof(keybuf))
2092 return NULL;
2093
2094 /*
2095 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2096 * than 16 bytes.
2097 */
2098 pad_len = key_len % 8;
2099 if (pad_len)
2100 pad_len = 8 - pad_len;
2101 if (key_len + pad_len < 16)
2102 pad_len += 8;
5bfc46bb 2103 if (pad_len && key_len < sizeof(keybuf)) {
6fc6879b
JM
2104 os_memcpy(keybuf, gsm->GTK[gsm->GN - 1], key_len);
2105 os_memset(keybuf + key_len, 0, pad_len);
2106 keybuf[key_len] = 0xdd;
2107 key_len += pad_len;
2108 key = keybuf;
2109 } else
2110 key = gsm->GTK[gsm->GN - 1];
2111
2112 /*
39eb4d08 2113 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
6fc6879b
JM
2114 * Key[5..32].
2115 */
39eb4d08 2116 subelem_len = 13 + key_len + 8;
6fc6879b
JM
2117 subelem = os_zalloc(subelem_len);
2118 if (subelem == NULL)
2119 return NULL;
2120
2121 subelem[0] = FTIE_SUBELEM_GTK;
39eb4d08
JM
2122 subelem[1] = 11 + key_len + 8;
2123 /* Key ID in B0-B1 of Key Info */
2124 WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
2125 subelem[4] = gsm->GTK_len;
2126 wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
98cd3d1c
JM
2127 if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, key_len / 8, key,
2128 subelem + 13)) {
6fc6879b
JM
2129 os_free(subelem);
2130 return NULL;
2131 }
2132
2133 *len = subelem_len;
2134 return subelem;
2135}
2136
2137
b27f13ed
JM
2138#ifdef CONFIG_IEEE80211W
2139static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
2140{
2141 u8 *subelem, *pos;
2142 struct wpa_group *gsm = sm->group;
2143 size_t subelem_len;
2144
ff89afb7
JM
2145 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2146 * Key[16+8] */
2147 subelem_len = 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN + 8;
b27f13ed
JM
2148 subelem = os_zalloc(subelem_len);
2149 if (subelem == NULL)
2150 return NULL;
2151
2152 pos = subelem;
2153 *pos++ = FTIE_SUBELEM_IGTK;
2154 *pos++ = subelem_len - 2;
2155 WPA_PUT_LE16(pos, gsm->GN_igtk);
2156 pos += 2;
9008a3e4 2157 wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
b27f13ed 2158 pos += 6;
ff89afb7 2159 *pos++ = WPA_IGTK_LEN;
98cd3d1c 2160 if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, WPA_IGTK_LEN / 8,
b27f13ed
JM
2161 gsm->IGTK[gsm->GN_igtk - 4], pos)) {
2162 os_free(subelem);
2163 return NULL;
2164 }
2165
2166 *len = subelem_len;
2167 return subelem;
2168}
2169#endif /* CONFIG_IEEE80211W */
2170
2171
88b32a99
SP
2172static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm,
2173 u8 *pos, u8 *end, u8 id, u8 descr_count,
f238cf9f
JM
2174 const u8 *ies, size_t ies_len)
2175{
2176 struct ieee802_11_elems parse;
2177 struct rsn_rdie *rdie;
2178
2179 wpa_printf(MSG_DEBUG, "FT: Resource Request: id=%d descr_count=%d",
2180 id, descr_count);
2181 wpa_hexdump(MSG_MSGDUMP, "FT: Resource descriptor IE(s)",
2182 ies, ies_len);
2183
2184 if (end - pos < (int) sizeof(*rdie)) {
2185 wpa_printf(MSG_ERROR, "FT: Not enough room for response RDIE");
2186 return pos;
2187 }
2188
2189 *pos++ = WLAN_EID_RIC_DATA;
2190 *pos++ = sizeof(*rdie);
2191 rdie = (struct rsn_rdie *) pos;
2192 rdie->id = id;
2193 rdie->descr_count = 0;
2194 rdie->status_code = host_to_le16(WLAN_STATUS_SUCCESS);
2195 pos += sizeof(*rdie);
2196
2197 if (ieee802_11_parse_elems((u8 *) ies, ies_len, &parse, 1) ==
2198 ParseFailed) {
2199 wpa_printf(MSG_DEBUG, "FT: Failed to parse request IEs");
2200 rdie->status_code =
2201 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
2202 return pos;
2203 }
2204
25310368 2205 if (parse.wmm_tspec) {
f238cf9f 2206 struct wmm_tspec_element *tspec;
f238cf9f
JM
2207
2208 if (parse.wmm_tspec_len + 2 < (int) sizeof(*tspec)) {
2209 wpa_printf(MSG_DEBUG, "FT: Too short WMM TSPEC IE "
2210 "(%d)", (int) parse.wmm_tspec_len);
2211 rdie->status_code =
2212 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
2213 return pos;
2214 }
2215 if (end - pos < (int) sizeof(*tspec)) {
2216 wpa_printf(MSG_ERROR, "FT: Not enough room for "
2217 "response TSPEC");
2218 rdie->status_code =
2219 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
2220 return pos;
2221 }
2222 tspec = (struct wmm_tspec_element *) pos;
2223 os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec));
25310368
JM
2224 }
2225
2226#ifdef NEED_AP_MLME
2227 if (parse.wmm_tspec && sm->wpa_auth->conf.ap_mlme) {
2228 int res;
2229
2230 res = wmm_process_tspec((struct wmm_tspec_element *) pos);
f238cf9f
JM
2231 wpa_printf(MSG_DEBUG, "FT: ADDTS processing result: %d", res);
2232 if (res == WMM_ADDTS_STATUS_INVALID_PARAMETERS)
2233 rdie->status_code =
2234 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS);
2235 else if (res == WMM_ADDTS_STATUS_REFUSED)
2236 rdie->status_code =
2237 host_to_le16(WLAN_STATUS_REQUEST_DECLINED);
2238 else {
2239 /* TSPEC accepted; include updated TSPEC in response */
2240 rdie->descr_count = 1;
25310368 2241 pos += sizeof(struct wmm_tspec_element);
f238cf9f
JM
2242 }
2243 return pos;
2244 }
fe6bdb77 2245#endif /* NEED_AP_MLME */
f238cf9f 2246
88b32a99 2247 if (parse.wmm_tspec && !sm->wpa_auth->conf.ap_mlme) {
88b32a99
SP
2248 int res;
2249
88b32a99 2250 res = wpa_ft_add_tspec(sm->wpa_auth, sm->addr, pos,
25310368 2251 sizeof(struct wmm_tspec_element));
88b32a99
SP
2252 if (res >= 0) {
2253 if (res)
2254 rdie->status_code = host_to_le16(res);
2255 else {
2256 /* TSPEC accepted; include updated TSPEC in
2257 * response */
006309b5 2258 rdie->descr_count = 1;
25310368 2259 pos += sizeof(struct wmm_tspec_element);
88b32a99
SP
2260 }
2261 return pos;
2262 }
2263 }
2264
f238cf9f
JM
2265 wpa_printf(MSG_DEBUG, "FT: No supported resource requested");
2266 rdie->status_code = host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE);
2267 return pos;
2268}
2269
2270
88b32a99
SP
2271static u8 * wpa_ft_process_ric(struct wpa_state_machine *sm, u8 *pos, u8 *end,
2272 const u8 *ric, size_t ric_len)
f238cf9f
JM
2273{
2274 const u8 *rpos, *start;
2275 const struct rsn_rdie *rdie;
2276
2277 wpa_hexdump(MSG_MSGDUMP, "FT: RIC Request", ric, ric_len);
2278
2279 rpos = ric;
2280 while (rpos + sizeof(*rdie) < ric + ric_len) {
2281 if (rpos[0] != WLAN_EID_RIC_DATA || rpos[1] < sizeof(*rdie) ||
2282 rpos + 2 + rpos[1] > ric + ric_len)
2283 break;
2284 rdie = (const struct rsn_rdie *) (rpos + 2);
2285 rpos += 2 + rpos[1];
2286 start = rpos;
2287
2288 while (rpos + 2 <= ric + ric_len &&
2289 rpos + 2 + rpos[1] <= ric + ric_len) {
2290 if (rpos[0] == WLAN_EID_RIC_DATA)
2291 break;
2292 rpos += 2 + rpos[1];
2293 }
88b32a99 2294 pos = wpa_ft_process_rdie(sm, pos, end, rdie->id,
f238cf9f
JM
2295 rdie->descr_count,
2296 start, rpos - start);
2297 }
2298
2299 return pos;
2300}
2301
2302
6fc6879b 2303u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
f238cf9f
JM
2304 size_t max_len, int auth_alg,
2305 const u8 *req_ies, size_t req_ies_len)
6fc6879b 2306{
738a1cb2
JM
2307 u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
2308 size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
6fc6879b
JM
2309 int res;
2310 struct wpa_auth_config *conf;
2311 struct rsn_ftie *_ftie;
f238cf9f
JM
2312 struct wpa_ft_ies parse;
2313 u8 *ric_start;
6e80516a 2314 u8 *anonce, *snonce;
2f373878
JM
2315 const u8 *kck;
2316 size_t kck_len;
6fc6879b
JM
2317
2318 if (sm == NULL)
2319 return pos;
2320
2321 conf = &sm->wpa_auth->conf;
2322
aa189ac9 2323 if (!wpa_key_mgmt_ft(sm->wpa_key_mgmt))
6fc6879b
JM
2324 return pos;
2325
2326 end = pos + max_len;
2327
738a1cb2
JM
2328 if (auth_alg == WLAN_AUTH_FT) {
2329 /*
2330 * RSN (only present if this is a Reassociation Response and
2331 * part of a fast BSS transition)
2332 */
2333 res = wpa_write_rsn_ie(conf, pos, end - pos, sm->pmk_r1_name);
2334 if (res < 0)
2335 return pos;
2336 rsnie = pos;
2337 rsnie_len = res;
2338 pos += res;
2339 }
6fc6879b
JM
2340
2341 /* Mobility Domain Information */
2342 res = wpa_write_mdie(conf, pos, end - pos);
2343 if (res < 0)
2344 return pos;
2345 mdie = pos;
2346 mdie_len = res;
2347 pos += res;
2348
2349 /* Fast BSS Transition Information */
2350 if (auth_alg == WLAN_AUTH_FT) {
2351 subelem = wpa_ft_gtk_subelem(sm, &subelem_len);
2352 r0kh_id = sm->r0kh_id;
2353 r0kh_id_len = sm->r0kh_id_len;
6e80516a
JM
2354 anonce = sm->ANonce;
2355 snonce = sm->SNonce;
b27f13ed
JM
2356#ifdef CONFIG_IEEE80211W
2357 if (sm->mgmt_frame_prot) {
2358 u8 *igtk;
2359 size_t igtk_len;
2360 u8 *nbuf;
2361 igtk = wpa_ft_igtk_subelem(sm, &igtk_len);
2362 if (igtk == NULL) {
2363 os_free(subelem);
2364 return pos;
2365 }
2366 nbuf = os_realloc(subelem, subelem_len + igtk_len);
2367 if (nbuf == NULL) {
2368 os_free(subelem);
2369 os_free(igtk);
2370 return pos;
2371 }
2372 subelem = nbuf;
2373 os_memcpy(subelem + subelem_len, igtk, igtk_len);
2374 subelem_len += igtk_len;
2375 os_free(igtk);
2376 }
2377#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
2378 } else {
2379 r0kh_id = conf->r0_key_holder;
2380 r0kh_id_len = conf->r0_key_holder_len;
6e80516a
JM
2381 anonce = NULL;
2382 snonce = NULL;
6fc6879b 2383 }
6e80516a 2384 res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos,
6fc6879b
JM
2385 end - pos, subelem, subelem_len);
2386 os_free(subelem);
2387 if (res < 0)
2388 return pos;
2389 ftie = pos;
2390 ftie_len = res;
2391 pos += res;
2392
2393 _ftie = (struct rsn_ftie *) (ftie + 2);
1f6e69e0
JM
2394 if (auth_alg == WLAN_AUTH_FT)
2395 _ftie->mic_control[1] = 3; /* Information element count */
f238cf9f
JM
2396
2397 ric_start = pos;
2398 if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse) == 0 && parse.ric) {
88b32a99
SP
2399 pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
2400 parse.ric_len);
1f6e69e0
JM
2401 if (auth_alg == WLAN_AUTH_FT)
2402 _ftie->mic_control[1] +=
2403 ieee802_11_ie_count(ric_start,
2404 pos - ric_start);
f238cf9f
JM
2405 }
2406 if (ric_start == pos)
2407 ric_start = NULL;
2408
2f373878
JM
2409 if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
2410 kck = sm->PTK.kck2;
2411 kck_len = sm->PTK.kck2_len;
2412 } else {
2413 kck = sm->PTK.kck;
2414 kck_len = sm->PTK.kck_len;
2415 }
1f6e69e0 2416 if (auth_alg == WLAN_AUTH_FT &&
2f373878 2417 wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 6,
6fc6879b 2418 mdie, mdie_len, ftie, ftie_len,
f238cf9f
JM
2419 rsnie, rsnie_len,
2420 ric_start, ric_start ? pos - ric_start : 0,
2421 _ftie->mic) < 0)
6fc6879b
JM
2422 wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
2423
e44bd28c
JM
2424 os_free(sm->assoc_resp_ftie);
2425 sm->assoc_resp_ftie = os_malloc(ftie_len);
2426 if (sm->assoc_resp_ftie)
2427 os_memcpy(sm->assoc_resp_ftie, ftie, ftie_len);
2428
6fc6879b
JM
2429 return pos;
2430}
2431
2432
6fc6879b
JM
2433static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
2434 int vlan_id,
71934751 2435 enum wpa_alg alg, const u8 *addr, int idx,
6fc6879b
JM
2436 u8 *key, size_t key_len)
2437{
cef8fac0 2438 if (wpa_auth->cb->set_key == NULL)
6fc6879b 2439 return -1;
cef8fac0
JB
2440 return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
2441 key, key_len);
6fc6879b
JM
2442}
2443
2444
0e84c254 2445void wpa_ft_install_ptk(struct wpa_state_machine *sm)
6fc6879b 2446{
71934751 2447 enum wpa_alg alg;
6fc6879b
JM
2448 int klen;
2449
2450 /* MLME-SETKEYS.request(PTK) */
c3550295
JM
2451 alg = wpa_cipher_to_alg(sm->pairwise);
2452 klen = wpa_cipher_key_len(sm->pairwise);
2453 if (!wpa_cipher_valid_pairwise(sm->pairwise)) {
0e84c254
JM
2454 wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip "
2455 "PTK configuration", sm->pairwise);
6fc6879b 2456 return;
0e84c254 2457 }
6fc6879b 2458
0e3bd7ac
MV
2459 if (sm->tk_already_set) {
2460 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2461 * PN in the driver */
2462 wpa_printf(MSG_DEBUG,
2463 "FT: Do not re-install same PTK to the driver");
2464 return;
2465 }
2466
6fc6879b
JM
2467 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2468 * most likely without this.. At the moment, STA entry is added only
0e84c254
JM
2469 * after association has been completed. This function will be called
2470 * again after association to get the PTK configured, but that could be
2471 * optimized by adding the STA entry earlier.
6fc6879b
JM
2472 */
2473 if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
98cd3d1c 2474 sm->PTK.tk, klen))
6fc6879b
JM
2475 return;
2476
2477 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2478 sm->pairwise_set = TRUE;
0e3bd7ac 2479 sm->tk_already_set = TRUE;
6fc6879b
JM
2480}
2481
2482
96590564
MB
2483/* Derive PMK-R1 from PSK, check all available PSK */
2484static int wpa_ft_psk_pmk_r1(struct wpa_state_machine *sm,
2485 const u8 *req_pmk_r1_name,
17010c38 2486 u8 *out_pmk_r1, int *out_pairwise,
069b4e30
MB
2487 struct vlan_description *out_vlan,
2488 const u8 **out_identity, size_t *out_identity_len,
2489 const u8 **out_radius_cui,
a6509e85
MB
2490 size_t *out_radius_cui_len,
2491 int *out_session_timeout)
96590564
MB
2492{
2493 const u8 *pmk = NULL;
2494 u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
2495 u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
2496 struct wpa_authenticator *wpa_auth = sm->wpa_auth;
2497 const u8 *mdid = wpa_auth->conf.mobility_domain;
2498 const u8 *r0kh = sm->r0kh_id;
2499 size_t r0kh_len = sm->r0kh_id_len;
2500 const u8 *r1kh = wpa_auth->conf.r1_key_holder;
2501 const u8 *ssid = wpa_auth->conf.ssid;
2502 size_t ssid_len = wpa_auth->conf.ssid_len;
2503 int pairwise;
2504
2505 pairwise = sm->pairwise;
2506
2507 for (;;) {
2508 pmk = wpa_ft_get_psk(wpa_auth, sm->addr, sm->p2p_dev_addr,
2509 pmk);
2510 if (pmk == NULL)
2511 break;
2512
364c064a
JM
2513 if (wpa_derive_pmk_r0(pmk, PMK_LEN, ssid, ssid_len, mdid, r0kh,
2514 r0kh_len, sm->addr,
2515 pmk_r0, pmk_r0_name) < 0 ||
a3e18dbb
JM
2516 wpa_derive_pmk_r1(pmk_r0, PMK_LEN, pmk_r0_name, r1kh,
2517 sm->addr, pmk_r1, pmk_r1_name) < 0 ||
364c064a 2518 os_memcmp_const(pmk_r1_name, req_pmk_r1_name,
96590564
MB
2519 WPA_PMK_NAME_LEN) != 0)
2520 continue;
2521
2522 /* We found a PSK that matches the requested pmk_r1_name */
2523 wpa_printf(MSG_DEBUG,
2524 "FT: Found PSK to generate PMK-R1 locally");
2525 os_memcpy(out_pmk_r1, pmk_r1, PMK_LEN);
2526 if (out_pairwise)
2527 *out_pairwise = pairwise;
17010c38
MB
2528 if (out_vlan &&
2529 wpa_ft_get_vlan(sm->wpa_auth, sm->addr, out_vlan) < 0) {
2530 wpa_printf(MSG_DEBUG, "FT: vlan not available for STA "
2531 MACSTR, MAC2STR(sm->addr));
2532 return -1;
2533 }
2534
069b4e30
MB
2535 if (out_identity && out_identity_len) {
2536 *out_identity_len = wpa_ft_get_identity(
2537 sm->wpa_auth, sm->addr, out_identity);
2538 }
2539
2540 if (out_radius_cui && out_radius_cui_len) {
2541 *out_radius_cui_len = wpa_ft_get_radius_cui(
2542 sm->wpa_auth, sm->addr, out_radius_cui);
2543 }
2544
a6509e85
MB
2545 if (out_session_timeout) {
2546 *out_session_timeout = wpa_ft_get_session_timeout(
2547 sm->wpa_auth, sm->addr);
2548 }
2549
96590564
MB
2550 return 0;
2551 }
2552
2553 wpa_printf(MSG_DEBUG,
2554 "FT: Did not find PSK to generate PMK-R1 locally");
2555 return -1;
2556}
2557
2558
2559/* Detect the configuration the station asked for.
2560 * Required to detect FT-PSK and pairwise cipher.
2561 */
2562static int wpa_ft_set_key_mgmt(struct wpa_state_machine *sm,
2563 struct wpa_ft_ies *parse)
2564{
2565 int key_mgmt, ciphers;
2566
2567 if (sm->wpa_key_mgmt)
2568 return 0;
2569
2570 key_mgmt = parse->key_mgmt & sm->wpa_auth->conf.wpa_key_mgmt;
2571 if (!key_mgmt) {
2572 wpa_printf(MSG_DEBUG, "FT: Invalid key mgmt (0x%x) from "
2573 MACSTR, parse->key_mgmt, MAC2STR(sm->addr));
2574 return -1;
2575 }
2576 if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
2577 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
c22bb5bb
JM
2578#ifdef CONFIG_SHA384
2579 else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
2580 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
2581#endif /* CONFIG_SHA384 */
96590564
MB
2582 else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
2583 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
5aa08153
JM
2584#ifdef CONFIG_FILS
2585 else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256)
2586 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256;
2587 else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384)
2588 sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384;
2589#endif /* CONFIG_FILS */
96590564
MB
2590 ciphers = parse->pairwise_cipher & sm->wpa_auth->conf.rsn_pairwise;
2591 if (!ciphers) {
2592 wpa_printf(MSG_DEBUG, "FT: Invalid pairwise cipher (0x%x) from "
2593 MACSTR,
2594 parse->pairwise_cipher, MAC2STR(sm->addr));
2595 return -1;
2596 }
2597 sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
2598
2599 return 0;
2600}
2601
2602
4ddca814
JM
2603static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator *wpa_auth,
2604 struct wpa_state_machine *sm,
2605 const u8 *r0kh_id, size_t r0kh_id_len,
2606 const u8 *req_pmk_r0_name,
2607 const u8 *req_pmk_r1_name,
17010c38 2608 u8 *out_pmk_r1, int *out_pairwise,
069b4e30
MB
2609 struct vlan_description *vlan,
2610 const u8 **identity, size_t *identity_len,
2611 const u8 **radius_cui,
a6509e85
MB
2612 size_t *radius_cui_len,
2613 int *out_session_timeout)
4ddca814
JM
2614{
2615 struct wpa_auth_config *conf = &wpa_auth->conf;
2616 const struct wpa_ft_pmk_r0_sa *r0;
2617 u8 pmk_r1_name[WPA_PMK_NAME_LEN];
3a3e2832 2618 int expires_in = 0;
a6509e85
MB
2619 int session_timeout = 0;
2620 struct os_reltime now;
4ddca814
JM
2621
2622 if (conf->r0_key_holder_len != r0kh_id_len ||
2623 os_memcmp(conf->r0_key_holder, r0kh_id, conf->r0_key_holder_len) !=
2624 0)
2625 return -1; /* not our R0KH-ID */
2626
2627 wpa_printf(MSG_DEBUG, "FT: STA R0KH-ID matching local configuration");
2628 if (wpa_ft_fetch_pmk_r0(sm->wpa_auth, sm->addr, req_pmk_r0_name, &r0) <
2629 0)
2630 return -1; /* no matching PMKR0Name in local cache */
2631
2632 wpa_printf(MSG_DEBUG, "FT: Requested PMKR0Name found in local cache");
2633
a3e18dbb
JM
2634 if (wpa_derive_pmk_r1(r0->pmk_r0, r0->pmk_r0_len, r0->pmk_r0_name,
2635 conf->r1_key_holder,
4ddca814
JM
2636 sm->addr, out_pmk_r1, pmk_r1_name) < 0)
2637 return -1;
a3e18dbb 2638 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", out_pmk_r1, r0->pmk_r0_len);
4ddca814
JM
2639 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
2640
a6509e85
MB
2641 os_get_reltime(&now);
2642 if (r0->expiration)
3a3e2832 2643 expires_in = r0->expiration - now.sec;
a6509e85
MB
2644
2645 if (r0->session_timeout)
2646 session_timeout = r0->session_timeout - now.sec;
3a3e2832 2647
a3e18dbb
JM
2648 wpa_ft_store_pmk_r1(wpa_auth, sm->addr, out_pmk_r1, r0->pmk_r0_len,
2649 pmk_r1_name,
a6509e85 2650 sm->pairwise, r0->vlan, expires_in, session_timeout,
069b4e30
MB
2651 r0->identity, r0->identity_len,
2652 r0->radius_cui, r0->radius_cui_len);
4ddca814
JM
2653
2654 *out_pairwise = sm->pairwise;
17010c38
MB
2655 if (vlan) {
2656 if (r0->vlan)
2657 *vlan = *r0->vlan;
2658 else
2659 os_memset(vlan, 0, sizeof(*vlan));
2660 }
069b4e30
MB
2661
2662 if (identity && identity_len) {
2663 *identity = r0->identity;
2664 *identity_len = r0->identity_len;
2665 }
2666
2667 if (radius_cui && radius_cui_len) {
2668 *radius_cui = r0->radius_cui;
2669 *radius_cui_len = r0->radius_cui_len;
2670 }
2671
a6509e85
MB
2672 *out_session_timeout = session_timeout;
2673
4ddca814
JM
2674 return 0;
2675}
2676
2677
692ec305 2678static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
6fc6879b
JM
2679 const u8 *ies, size_t ies_len,
2680 u8 **resp_ies, size_t *resp_ies_len)
2681{
2682 struct rsn_mdie *mdie;
2683 struct rsn_ftie *ftie;
a3e18dbb 2684 u8 pmk_r1[PMK_LEN_MAX], pmk_r1_name[WPA_PMK_NAME_LEN];
6fc6879b
JM
2685 u8 ptk_name[WPA_PMK_NAME_LEN];
2686 struct wpa_auth_config *conf;
2687 struct wpa_ft_ies parse;
98cd3d1c 2688 size_t buflen;
6fc6879b
JM
2689 int ret;
2690 u8 *pos, *end;
a6509e85 2691 int pairwise, session_timeout = 0;
17010c38 2692 struct vlan_description vlan;
069b4e30
MB
2693 const u8 *identity, *radius_cui;
2694 size_t identity_len = 0, radius_cui_len = 0;
a3e18dbb
JM
2695 int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
2696 size_t pmk_r1_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;
6fc6879b
JM
2697
2698 *resp_ies = NULL;
2699 *resp_ies_len = 0;
2700
2701 sm->pmk_r1_name_valid = 0;
2702 conf = &sm->wpa_auth->conf;
2703
2704 wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
2705 ies, ies_len);
2706
2707 if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
2708 wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
2709 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2710 }
2711
2712 mdie = (struct rsn_mdie *) parse.mdie;
2713 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
2714 os_memcmp(mdie->mobility_domain,
2715 sm->wpa_auth->conf.mobility_domain,
2716 MOBILITY_DOMAIN_ID_LEN) != 0) {
2717 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
2718 return WLAN_STATUS_INVALID_MDIE;
2719 }
2720
2721 ftie = (struct rsn_ftie *) parse.ftie;
2722 if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
2723 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
2724 return WLAN_STATUS_INVALID_FTIE;
2725 }
2726
2727 os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
2728
2729 if (parse.r0kh_id == NULL) {
2730 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
2731 return WLAN_STATUS_INVALID_FTIE;
2732 }
2733
2734 wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID",
2735 parse.r0kh_id, parse.r0kh_id_len);
2736 os_memcpy(sm->r0kh_id, parse.r0kh_id, parse.r0kh_id_len);
2737 sm->r0kh_id_len = parse.r0kh_id_len;
2738
2739 if (parse.rsn_pmkid == NULL) {
2740 wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
2741 return WLAN_STATUS_INVALID_PMKID;
2742 }
2743
96590564
MB
2744 if (wpa_ft_set_key_mgmt(sm, &parse) < 0)
2745 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2746
6fc6879b
JM
2747 wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name",
2748 parse.rsn_pmkid, WPA_PMK_NAME_LEN);
364c064a
JM
2749 if (wpa_derive_pmk_r1_name(parse.rsn_pmkid,
2750 sm->wpa_auth->conf.r1_key_holder, sm->addr,
2751 pmk_r1_name) < 0)
2752 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2753 wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
2754 pmk_r1_name, WPA_PMK_NAME_LEN);
2755
96590564
MB
2756 if (conf->ft_psk_generate_local &&
2757 wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) {
17010c38 2758 if (wpa_ft_psk_pmk_r1(sm, pmk_r1_name, pmk_r1, &pairwise,
069b4e30 2759 &vlan, &identity, &identity_len,
a6509e85
MB
2760 &radius_cui, &radius_cui_len,
2761 &session_timeout) < 0)
96590564 2762 return WLAN_STATUS_INVALID_PMKID;
4ddca814
JM
2763 wpa_printf(MSG_DEBUG,
2764 "FT: Generated PMK-R1 for FT-PSK locally");
96590564 2765 } else if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name,
a3e18dbb
JM
2766 pmk_r1, &pmk_r1_len, &pairwise, &vlan,
2767 &identity, &identity_len, &radius_cui,
a6509e85 2768 &radius_cui_len, &session_timeout) < 0) {
4ddca814
JM
2769 wpa_printf(MSG_DEBUG,
2770 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2771 if (wpa_ft_local_derive_pmk_r1(sm->wpa_auth, sm,
2772 parse.r0kh_id, parse.r0kh_id_len,
2773 parse.rsn_pmkid,
17010c38 2774 pmk_r1_name, pmk_r1, &pairwise,
069b4e30 2775 &vlan, &identity, &identity_len,
a6509e85
MB
2776 &radius_cui, &radius_cui_len,
2777 &session_timeout) == 0) {
4ddca814
JM
2778 wpa_printf(MSG_DEBUG,
2779 "FT: Generated PMK-R1 based on local PMK-R0");
2780 goto pmk_r1_derived;
2781 }
2782
692ec305 2783 if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) {
3a46cf93
MB
2784 wpa_printf(MSG_DEBUG,
2785 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
6fc6879b
JM
2786 return WLAN_STATUS_INVALID_PMKID;
2787 }
2788
692ec305 2789 return -1; /* Status pending */
4ddca814
JM
2790 } else {
2791 wpa_printf(MSG_DEBUG, "FT: Found PMKR1Name from local cache");
6fc6879b
JM
2792 }
2793
4ddca814 2794pmk_r1_derived:
a3e18dbb 2795 wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, pmk_r1_len);
6fc6879b
JM
2796 sm->pmk_r1_name_valid = 1;
2797 os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
2798
3642c431 2799 if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
6fc6879b
JM
2800 wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
2801 "ANonce");
2802 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2803 }
2804
2805 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
2806 sm->SNonce, WPA_NONCE_LEN);
2807 wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
2808 sm->ANonce, WPA_NONCE_LEN);
2809
a3e18dbb
JM
2810 if (wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
2811 sm->addr, sm->wpa_auth->addr, pmk_r1_name,
98cd3d1c
JM
2812 &sm->PTK, ptk_name, sm->wpa_key_mgmt,
2813 pairwise) < 0)
2814 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b 2815
0e84c254 2816 sm->pairwise = pairwise;
3d4d2348 2817 sm->PTK_valid = TRUE;
0e3bd7ac 2818 sm->tk_already_set = FALSE;
6fc6879b
JM
2819 wpa_ft_install_ptk(sm);
2820
17010c38
MB
2821 if (wpa_ft_set_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) {
2822 wpa_printf(MSG_DEBUG, "FT: Failed to configure VLAN");
2823 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2824 }
069b4e30
MB
2825 if (wpa_ft_set_identity(sm->wpa_auth, sm->addr,
2826 identity, identity_len) < 0 ||
2827 wpa_ft_set_radius_cui(sm->wpa_auth, sm->addr,
2828 radius_cui, radius_cui_len) < 0) {
2829 wpa_printf(MSG_DEBUG, "FT: Failed to configure identity/CUI");
2830 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2831 }
a6509e85 2832 wpa_ft_set_session_timeout(sm->wpa_auth, sm->addr, session_timeout);
17010c38 2833
6fc6879b
JM
2834 buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
2835 2 + FT_R1KH_ID_LEN + 200;
2836 *resp_ies = os_zalloc(buflen);
a8e25dee
JM
2837 if (*resp_ies == NULL)
2838 goto fail;
6fc6879b
JM
2839
2840 pos = *resp_ies;
2841 end = *resp_ies + buflen;
2842
2843 ret = wpa_write_rsn_ie(conf, pos, end - pos, parse.rsn_pmkid);
a8e25dee
JM
2844 if (ret < 0)
2845 goto fail;
6fc6879b
JM
2846 pos += ret;
2847
2848 ret = wpa_write_mdie(conf, pos, end - pos);
a8e25dee
JM
2849 if (ret < 0)
2850 goto fail;
6fc6879b
JM
2851 pos += ret;
2852
2853 ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len,
2854 sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
a8e25dee
JM
2855 if (ret < 0)
2856 goto fail;
6fc6879b
JM
2857 pos += ret;
2858
2859 *resp_ies_len = pos - *resp_ies;
2860
2861 return WLAN_STATUS_SUCCESS;
a8e25dee
JM
2862fail:
2863 os_free(*resp_ies);
2864 *resp_ies = NULL;
2865 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2866}
2867
2868
2869void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
2870 u16 auth_transaction, const u8 *ies, size_t ies_len,
2871 void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
2872 u16 auth_transaction, u16 status,
2873 const u8 *ies, size_t ies_len),
2874 void *ctx)
2875{
2876 u16 status;
2877 u8 *resp_ies;
2878 size_t resp_ies_len;
692ec305 2879 int res;
6fc6879b
JM
2880
2881 if (sm == NULL) {
2882 wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but "
2883 "WPA SM not available");
2884 return;
2885 }
2886
2887 wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
2888 " BSSID=" MACSTR " transaction=%d",
2889 MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
692ec305
JM
2890 sm->ft_pending_cb = cb;
2891 sm->ft_pending_cb_ctx = ctx;
2892 sm->ft_pending_auth_transaction = auth_transaction;
3a46cf93 2893 sm->ft_pending_pull_left_retries = sm->wpa_auth->conf.rkh_pull_retries;
692ec305
JM
2894 res = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
2895 &resp_ies_len);
2896 if (res < 0) {
2897 wpa_printf(MSG_DEBUG, "FT: Callback postponed until response is available");
2898 return;
2899 }
2900 status = res;
6fc6879b
JM
2901
2902 wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR
2903 " auth_transaction=%d status=%d",
2904 MAC2STR(sm->addr), auth_transaction + 1, status);
2905 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
2906 cb(ctx, sm->addr, bssid, auth_transaction + 1, status,
2907 resp_ies, resp_ies_len);
2908 os_free(resp_ies);
2909}
2910
2911
2912u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
2913 size_t ies_len)
2914{
2915 struct wpa_ft_ies parse;
2916 struct rsn_mdie *mdie;
2917 struct rsn_ftie *ftie;
98cd3d1c
JM
2918 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
2919 size_t mic_len = 16;
8aaf894d 2920 unsigned int count;
2f373878
JM
2921 const u8 *kck;
2922 size_t kck_len;
6fc6879b
JM
2923
2924 if (sm == NULL)
2925 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2926
2927 wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
2928
2929 if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
2930 wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
2931 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2932 }
2933
2934 if (parse.rsn == NULL) {
2935 wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req");
2936 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2937 }
2938
2939 if (parse.rsn_pmkid == NULL) {
2940 wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
2941 return WLAN_STATUS_INVALID_PMKID;
2942 }
2943
870834a1
JM
2944 if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)
2945 != 0) {
6fc6879b
JM
2946 wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match "
2947 "with the PMKR1Name derived from auth request");
2948 return WLAN_STATUS_INVALID_PMKID;
2949 }
2950
2951 mdie = (struct rsn_mdie *) parse.mdie;
2952 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
2953 os_memcmp(mdie->mobility_domain,
2954 sm->wpa_auth->conf.mobility_domain,
2955 MOBILITY_DOMAIN_ID_LEN) != 0) {
2956 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
2957 return WLAN_STATUS_INVALID_MDIE;
2958 }
2959
2960 ftie = (struct rsn_ftie *) parse.ftie;
2961 if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
2962 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
2963 return WLAN_STATUS_INVALID_FTIE;
2964 }
2965
0ae145cd
JM
2966 if (os_memcmp(ftie->snonce, sm->SNonce, WPA_NONCE_LEN) != 0) {
2967 wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
2968 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
2969 ftie->snonce, WPA_NONCE_LEN);
2970 wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
2971 sm->SNonce, WPA_NONCE_LEN);
0a63635e 2972 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
2973 }
2974
2975 if (os_memcmp(ftie->anonce, sm->ANonce, WPA_NONCE_LEN) != 0) {
2976 wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
2977 wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
2978 ftie->anonce, WPA_NONCE_LEN);
2979 wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
2980 sm->ANonce, WPA_NONCE_LEN);
0a63635e 2981 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
2982 }
2983
2984
2985 if (parse.r0kh_id == NULL) {
2986 wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE");
0a63635e 2987 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
2988 }
2989
2990 if (parse.r0kh_id_len != sm->r0kh_id_len ||
870834a1
JM
2991 os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
2992 {
0ae145cd
JM
2993 wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
2994 "the current R0KH-ID");
2995 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
2996 parse.r0kh_id, parse.r0kh_id_len);
2997 wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
2998 sm->r0kh_id, sm->r0kh_id_len);
0a63635e 2999 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
3000 }
3001
3002 if (parse.r1kh_id == NULL) {
3003 wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE");
0a63635e 3004 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
3005 }
3006
870834a1
JM
3007 if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
3008 FT_R1KH_ID_LEN) != 0) {
0ae145cd
JM
3009 wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
3010 "ReassocReq");
3011 wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE",
3012 parse.r1kh_id, FT_R1KH_ID_LEN);
3013 wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID",
3014 sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
0a63635e 3015 return WLAN_STATUS_INVALID_FTIE;
0ae145cd
JM
3016 }
3017
3018 if (parse.rsn_pmkid == NULL ||
870834a1
JM
3019 os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
3020 {
0ae145cd
JM
3021 wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
3022 "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
0a63635e 3023 return WLAN_STATUS_INVALID_PMKID;
0ae145cd
JM
3024 }
3025
8aaf894d
JM
3026 count = 3;
3027 if (parse.ric)
c284b461 3028 count += ieee802_11_ie_count(parse.ric, parse.ric_len);
8aaf894d
JM
3029 if (ftie->mic_control[1] != count) {
3030 wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
3031 "Control: received %u expected %u",
3032 ftie->mic_control[1], count);
0a63635e 3033 return WLAN_STATUS_UNSPECIFIED_FAILURE;
8aaf894d
JM
3034 }
3035
2f373878
JM
3036 if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
3037 kck = sm->PTK.kck2;
3038 kck_len = sm->PTK.kck2_len;
3039 } else {
3040 kck = sm->PTK.kck;
3041 kck_len = sm->PTK.kck_len;
3042 }
3043 if (wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 5,
6fc6879b
JM
3044 parse.mdie - 2, parse.mdie_len + 2,
3045 parse.ftie - 2, parse.ftie_len + 2,
babfbf15
JM
3046 parse.rsn - 2, parse.rsn_len + 2,
3047 parse.ric, parse.ric_len,
6fc6879b
JM
3048 mic) < 0) {
3049 wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
3050 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3051 }
3052
98cd3d1c 3053 if (os_memcmp_const(mic, ftie->mic, mic_len) != 0) {
6fc6879b 3054 wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
88b32a99
SP
3055 wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
3056 MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
98cd3d1c
JM
3057 wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
3058 ftie->mic, mic_len);
3059 wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, mic_len);
88b32a99
SP
3060 wpa_hexdump(MSG_MSGDUMP, "FT: MDIE",
3061 parse.mdie - 2, parse.mdie_len + 2);
3062 wpa_hexdump(MSG_MSGDUMP, "FT: FTIE",
3063 parse.ftie - 2, parse.ftie_len + 2);
3064 wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
3065 parse.rsn - 2, parse.rsn_len + 2);
6fc6879b
JM
3066 return WLAN_STATUS_INVALID_FTIE;
3067 }
3068
3069 return WLAN_STATUS_SUCCESS;
3070}
3071
3072
3073int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
3074{
3075 const u8 *sta_addr, *target_ap;
3076 const u8 *ies;
3077 size_t ies_len;
3078 u8 action;
3079 struct ft_rrb_frame *frame;
3080
3081 if (sm == NULL)
3082 return -1;
3083
3084 /*
3085 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3086 * FT Request action frame body[variable]
3087 */
3088
3089 if (len < 14) {
3090 wpa_printf(MSG_DEBUG, "FT: Too short FT Action frame "
3091 "(len=%lu)", (unsigned long) len);
3092 return -1;
3093 }
3094
3095 action = data[1];
3096 sta_addr = data + 2;
3097 target_ap = data + 8;
3098 ies = data + 14;
3099 ies_len = len - 14;
3100
3101 wpa_printf(MSG_DEBUG, "FT: Received FT Action frame (STA=" MACSTR
3102 " Target AP=" MACSTR " Action=%d)",
3103 MAC2STR(sta_addr), MAC2STR(target_ap), action);
3104
3105 if (os_memcmp(sta_addr, sm->addr, ETH_ALEN) != 0) {
3106 wpa_printf(MSG_DEBUG, "FT: Mismatch in FT Action STA address: "
3107 "STA=" MACSTR " STA-Address=" MACSTR,
3108 MAC2STR(sm->addr), MAC2STR(sta_addr));
3109 return -1;
3110 }
3111
3112 /*
3113 * Do some sanity checking on the target AP address (not own and not
3114 * broadcast. This could be extended to filter based on a list of known
3115 * APs in the MD (if such a list were configured).
3116 */
3117 if ((target_ap[0] & 0x01) ||
3118 os_memcmp(target_ap, sm->wpa_auth->addr, ETH_ALEN) == 0) {
3119 wpa_printf(MSG_DEBUG, "FT: Invalid Target AP in FT Action "
3120 "frame");
3121 return -1;
3122 }
3123
3124 wpa_hexdump(MSG_MSGDUMP, "FT: Action frame body", ies, ies_len);
3125
1940559e
JM
3126 if (!sm->wpa_auth->conf.ft_over_ds) {
3127 wpa_printf(MSG_DEBUG, "FT: Over-DS option disabled - reject");
3128 return -1;
3129 }
3130
6fc6879b
JM
3131 /* RRB - Forward action frame to the target AP */
3132 frame = os_malloc(sizeof(*frame) + len);
2c48211c
JM
3133 if (frame == NULL)
3134 return -1;
6fc6879b
JM
3135 frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
3136 frame->packet_type = FT_PACKET_REQUEST;
3137 frame->action_length = host_to_le16(len);
3138 os_memcpy(frame->ap_address, sm->wpa_auth->addr, ETH_ALEN);
3139 os_memcpy(frame + 1, data, len);
3140
3141 wpa_ft_rrb_send(sm->wpa_auth, target_ap, (u8 *) frame,
3142 sizeof(*frame) + len);
3143 os_free(frame);
3144
3145 return 0;
3146}
3147
3148
692ec305
JM
3149static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid,
3150 u16 auth_transaction, u16 resp,
3151 const u8 *ies, size_t ies_len)
3152{
3153 struct wpa_state_machine *sm = ctx;
3154 wpa_printf(MSG_DEBUG, "FT: Over-the-DS RX request cb for " MACSTR,
3155 MAC2STR(sm->addr));
3156 wpa_ft_send_rrb_auth_resp(sm, sm->ft_pending_current_ap, sm->addr,
3157 WLAN_STATUS_SUCCESS, ies, ies_len);
3158}
3159
3160
6fc6879b
JM
3161static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
3162 const u8 *current_ap, const u8 *sta_addr,
3163 const u8 *body, size_t len)
3164{
3165 struct wpa_state_machine *sm;
3166 u16 status;
692ec305
JM
3167 u8 *resp_ies;
3168 size_t resp_ies_len;
3169 int res;
6fc6879b
JM
3170
3171 sm = wpa_ft_add_sta(wpa_auth, sta_addr);
3172 if (sm == NULL) {
3173 wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
3174 "RRB Request");
3175 return -1;
3176 }
3177
3178 wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);
3179
692ec305
JM
3180 sm->ft_pending_cb = wpa_ft_rrb_rx_request_cb;
3181 sm->ft_pending_cb_ctx = sm;
3182 os_memcpy(sm->ft_pending_current_ap, current_ap, ETH_ALEN);
3a46cf93 3183 sm->ft_pending_pull_left_retries = sm->wpa_auth->conf.rkh_pull_retries;
692ec305
JM
3184 res = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
3185 &resp_ies_len);
3186 if (res < 0) {
3187 wpa_printf(MSG_DEBUG, "FT: No immediate response available - wait for pull response");
3188 return 0;
3189 }
3190 status = res;
3191
3192 res = wpa_ft_send_rrb_auth_resp(sm, current_ap, sta_addr, status,
3193 resp_ies, resp_ies_len);
3194 os_free(resp_ies);
3195 return res;
3196}
3197
3198
3199static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm,
3200 const u8 *current_ap, const u8 *sta_addr,
3201 u16 status, const u8 *resp_ies,
3202 size_t resp_ies_len)
3203{
3204 struct wpa_authenticator *wpa_auth = sm->wpa_auth;
3205 size_t rlen;
3206 struct ft_rrb_frame *frame;
3207 u8 *pos;
6fc6879b
JM
3208
3209 wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
3210 " CurrentAP=" MACSTR " status=%d",
3211 MAC2STR(sm->addr), MAC2STR(current_ap), status);
3212 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
3213
3214 /* RRB - Forward action frame response to the Current AP */
3215
3216 /*
3217 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3218 * Status_Code[2] FT Request action frame body[variable]
3219 */
3220 rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;
3221
3222 frame = os_malloc(sizeof(*frame) + rlen);
692ec305 3223 if (frame == NULL)
2c48211c 3224 return -1;
6fc6879b
JM
3225 frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
3226 frame->packet_type = FT_PACKET_RESPONSE;
3227 frame->action_length = host_to_le16(rlen);
3228 os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN);
3229 pos = (u8 *) (frame + 1);
3230 *pos++ = WLAN_ACTION_FT;
3231 *pos++ = 2; /* Action: Response */
3232 os_memcpy(pos, sta_addr, ETH_ALEN);
3233 pos += ETH_ALEN;
3234 os_memcpy(pos, wpa_auth->addr, ETH_ALEN);
3235 pos += ETH_ALEN;
3236 WPA_PUT_LE16(pos, status);
3237 pos += 2;
692ec305 3238 if (resp_ies)
6fc6879b 3239 os_memcpy(pos, resp_ies, resp_ies_len);
6fc6879b
JM
3240
3241 wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
3242 sizeof(*frame) + rlen);
3243 os_free(frame);
3244
3245 return 0;
3246}
3247
3248
245fc96e
MB
3249static int wpa_ft_rrb_build_r0(const u8 *key, const size_t key_len,
3250 const struct tlv_list *tlvs,
3251 const struct wpa_ft_pmk_r0_sa *pmk_r0,
3252 const u8 *r1kh_id, const u8 *s1kh_id,
3253 const struct tlv_list *tlv_auth,
3254 const u8 *src_addr, u8 type,
3255 u8 **packet, size_t *packet_len)
3256{
a3e18dbb
JM
3257 u8 pmk_r1[PMK_LEN_MAX];
3258 size_t pmk_r1_len = pmk_r0->pmk_r0_len;
245fc96e
MB
3259 u8 pmk_r1_name[WPA_PMK_NAME_LEN];
3260 u8 f_pairwise[sizeof(le16)];
3a3e2832 3261 u8 f_expires_in[sizeof(le16)];
a6509e85 3262 u8 f_session_timeout[sizeof(le32)];
3a3e2832 3263 int expires_in;
a6509e85 3264 int session_timeout;
3a3e2832 3265 struct os_reltime now;
245fc96e
MB
3266 int ret;
3267 struct tlv_list sess_tlv[] = {
a3e18dbb 3268 { .type = FT_RRB_PMK_R1, .len = pmk_r1_len,
245fc96e
MB
3269 .data = pmk_r1 },
3270 { .type = FT_RRB_PMK_R1_NAME, .len = sizeof(pmk_r1_name),
3271 .data = pmk_r1_name },
3272 { .type = FT_RRB_PAIRWISE, .len = sizeof(f_pairwise),
3273 .data = f_pairwise },
3a3e2832
MB
3274 { .type = FT_RRB_EXPIRES_IN, .len = sizeof(f_expires_in),
3275 .data = f_expires_in },
069b4e30
MB
3276 { .type = FT_RRB_IDENTITY, .len = pmk_r0->identity_len,
3277 .data = pmk_r0->identity },
3278 { .type = FT_RRB_RADIUS_CUI, .len = pmk_r0->radius_cui_len,
3279 .data = pmk_r0->radius_cui },
a6509e85
MB
3280 { .type = FT_RRB_SESSION_TIMEOUT,
3281 .len = sizeof(f_session_timeout),
3282 .data = f_session_timeout },
245fc96e
MB
3283 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
3284 };
3285
a3e18dbb
JM
3286 if (wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_len,
3287 pmk_r0->pmk_r0_name, r1kh_id,
245fc96e
MB
3288 s1kh_id, pmk_r1, pmk_r1_name) < 0)
3289 return -1;
a3e18dbb
JM
3290 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 (for peer AP)",
3291 pmk_r1, pmk_r1_len);
3292 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name (for peer AP)",
3293 pmk_r1_name, WPA_PMK_NAME_LEN);
245fc96e
MB
3294 WPA_PUT_LE16(f_pairwise, pmk_r0->pairwise);
3295
3a3e2832
MB
3296 os_get_reltime(&now);
3297 if (pmk_r0->expiration > now.sec)
3298 expires_in = pmk_r0->expiration - now.sec;
3299 else if (pmk_r0->expiration)
3300 expires_in = 1;
3301 else
3302 expires_in = 0;
3303 WPA_PUT_LE16(f_expires_in, expires_in);
3304
a6509e85
MB
3305 if (pmk_r0->session_timeout > now.sec)
3306 session_timeout = pmk_r0->session_timeout - now.sec;
3307 else if (pmk_r0->session_timeout)
3308 session_timeout = 1;
3309 else
3310 session_timeout = 0;
3311 WPA_PUT_LE32(f_session_timeout, session_timeout);
3312
245fc96e 3313 ret = wpa_ft_rrb_build(key, key_len, tlvs, sess_tlv, tlv_auth,
17010c38
MB
3314 pmk_r0->vlan, src_addr, type,
3315 packet, packet_len);
245fc96e
MB
3316
3317 os_memset(pmk_r1, 0, sizeof(pmk_r1));
3318
3319 return ret;
3320}
3321
3322
6fc6879b
JM
3323static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
3324 const u8 *src_addr,
245fc96e 3325 const u8 *enc, size_t enc_len,
eefe8630
MB
3326 const u8 *auth, size_t auth_len,
3327 int no_defer)
6fc6879b 3328{
245fc96e
MB
3329 const char *msgtype = "pull request";
3330 u8 *plain = NULL, *packet = NULL;
3331 size_t plain_len = 0, packet_len = 0;
3a46cf93 3332 struct ft_remote_r1kh *r1kh, *r1kh_wildcard;
245fc96e
MB
3333 const u8 *key;
3334 size_t key_len;
eefe8630 3335 int seq_ret;
245fc96e
MB
3336 const u8 *f_nonce, *f_r0kh_id, *f_r1kh_id, *f_s1kh_id, *f_pmk_r0_name;
3337 size_t f_nonce_len, f_r0kh_id_len, f_r1kh_id_len, f_s1kh_id_len;
3338 size_t f_pmk_r0_name_len;
3339 const struct wpa_ft_pmk_r0_sa *r0;
3340 int ret;
3341 struct tlv_list resp[2];
eefe8630
MB
3342 struct tlv_list resp_auth[5];
3343 struct ft_rrb_seq f_seq;
6fc6879b
JM
3344
3345 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull");
3346
245fc96e
MB
3347 RRB_GET_AUTH(FT_RRB_R0KH_ID, r0kh_id, msgtype, -1);
3348 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID", f_r0kh_id, f_r0kh_id_len);
3349
3350 if (wpa_ft_rrb_check_r0kh(wpa_auth, f_r0kh_id, f_r0kh_id_len)) {
3351 wpa_printf(MSG_DEBUG, "FT: R0KH-ID mismatch");
3352 goto out;
3353 }
3354
3355 RRB_GET_AUTH(FT_RRB_R1KH_ID, r1kh_id, msgtype, FT_R1KH_ID_LEN);
3356 wpa_printf(MSG_DEBUG, "FT: R1KH-ID=" MACSTR, MAC2STR(f_r1kh_id));
3357
3a46cf93
MB
3358 wpa_ft_rrb_lookup_r1kh(wpa_auth, f_r1kh_id, &r1kh, &r1kh_wildcard);
3359 if (r1kh) {
3360 key = r1kh->key;
3361 key_len = sizeof(r1kh->key);
3362 } else if (r1kh_wildcard) {
3363 wpa_printf(MSG_DEBUG, "FT: Using wildcard R1KH-ID");
3364 key = r1kh_wildcard->key;
3365 key_len = sizeof(r1kh_wildcard->key);
3366 } else {
245fc96e 3367 goto out;
3a46cf93 3368 }
245fc96e
MB
3369
3370 RRB_GET_AUTH(FT_RRB_NONCE, nonce, "pull request", FT_RRB_NONCE_LEN);
3371 wpa_hexdump(MSG_DEBUG, "FT: nonce", f_nonce, f_nonce_len);
3372
3a46cf93
MB
3373 seq_ret = FT_RRB_SEQ_DROP;
3374 if (r1kh)
3375 seq_ret = wpa_ft_rrb_seq_chk(r1kh->seq, src_addr, enc, enc_len,
3376 auth, auth_len, msgtype, no_defer);
3377 if (!no_defer && r1kh_wildcard &&
3378 (!r1kh || os_memcmp(r1kh->addr, src_addr, ETH_ALEN) != 0)) {
3379 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3380 seq_ret = FT_RRB_SEQ_DEFER;
3381 }
3382
eefe8630
MB
3383 if (seq_ret == FT_RRB_SEQ_DROP)
3384 goto out;
3385
245fc96e
MB
3386 if (wpa_ft_rrb_decrypt(key, key_len, enc, enc_len, auth, auth_len,
3387 src_addr, FT_PACKET_R0KH_R1KH_PULL,
3388 &plain, &plain_len) < 0)
3389 goto out;
3390
3a46cf93
MB
3391 if (!r1kh)
3392 r1kh = wpa_ft_rrb_add_r1kh(wpa_auth, r1kh_wildcard, src_addr,
3393 f_r1kh_id,
3394 wpa_auth->conf.rkh_pos_timeout);
3395 if (!r1kh)
3396 goto out;
3397
eefe8630
MB
3398 if (seq_ret == FT_RRB_SEQ_DEFER) {
3399 wpa_ft_rrb_seq_req(wpa_auth, r1kh->seq, src_addr, f_r0kh_id,
3400 f_r0kh_id_len, f_r1kh_id, key, key_len,
3401 enc, enc_len, auth, auth_len,
3402 &wpa_ft_rrb_rx_pull);
3403 goto out;
3404 }
3405
3406 wpa_ft_rrb_seq_accept(wpa_auth, r1kh->seq, src_addr, auth, auth_len,
3407 msgtype);
3a46cf93
MB
3408 wpa_ft_rrb_r1kh_replenish(wpa_auth, r1kh,
3409 wpa_auth->conf.rkh_pos_timeout);
eefe8630 3410
245fc96e
MB
3411 RRB_GET(FT_RRB_PMK_R0_NAME, pmk_r0_name, msgtype, WPA_PMK_NAME_LEN);
3412 wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", f_pmk_r0_name,
3413 f_pmk_r0_name_len);
3414
3415 RRB_GET(FT_RRB_S1KH_ID, s1kh_id, msgtype, ETH_ALEN);
3416 wpa_printf(MSG_DEBUG, "FT: S1KH-ID=" MACSTR, MAC2STR(f_s1kh_id));
3417
eefe8630
MB
3418 if (wpa_ft_new_seq(r1kh->seq, &f_seq) < 0) {
3419 wpa_printf(MSG_DEBUG, "FT: Failed to get seq num");
3420 goto out;
3421 }
3422
245fc96e
MB
3423 resp[0].type = FT_RRB_S1KH_ID;
3424 resp[0].len = f_s1kh_id_len;
3425 resp[0].data = f_s1kh_id;
3426 resp[1].type = FT_RRB_LAST_EMPTY;
3427 resp[1].len = 0;
3428 resp[1].data = NULL;
3429
3430 resp_auth[0].type = FT_RRB_NONCE;
3431 resp_auth[0].len = f_nonce_len;
3432 resp_auth[0].data = f_nonce;
eefe8630
MB
3433 resp_auth[1].type = FT_RRB_SEQ;
3434 resp_auth[1].len = sizeof(f_seq);
3435 resp_auth[1].data = (u8 *) &f_seq;
3436 resp_auth[2].type = FT_RRB_R0KH_ID;
3437 resp_auth[2].len = f_r0kh_id_len;
3438 resp_auth[2].data = f_r0kh_id;
3439 resp_auth[3].type = FT_RRB_R1KH_ID;
3440 resp_auth[3].len = f_r1kh_id_len;
3441 resp_auth[3].data = f_r1kh_id;
3442 resp_auth[4].type = FT_RRB_LAST_EMPTY;
3443 resp_auth[4].len = 0;
3444 resp_auth[4].data = NULL;
245fc96e 3445
9fbe292f 3446 if (wpa_ft_fetch_pmk_r0(wpa_auth, f_s1kh_id, f_pmk_r0_name, &r0) < 0) {
245fc96e 3447 wpa_printf(MSG_DEBUG, "FT: No matching PMK-R0-Name found");
9fbe292f
MB
3448 ret = wpa_ft_rrb_build(key, key_len, resp, NULL, resp_auth,
3449 NULL, wpa_auth->addr,
3450 FT_PACKET_R0KH_R1KH_RESP,
3451 &packet, &packet_len);
3452 } else {
3453 ret = wpa_ft_rrb_build_r0(key, key_len, resp, r0, f_r1kh_id,
3454 f_s1kh_id, resp_auth, wpa_auth->addr,
3455 FT_PACKET_R0KH_R1KH_RESP,
3456 &packet, &packet_len);
3457 }
245fc96e
MB
3458
3459 if (!ret)
3460 wpa_ft_rrb_oui_send(wpa_auth, src_addr,
3461 FT_PACKET_R0KH_R1KH_RESP, packet,
3462 packet_len);
3463
3464out:
3465 os_free(plain);
3466 os_free(packet);
6fc6879b 3467
245fc96e
MB
3468 return 0;
3469}
6fc6879b 3470
6fc6879b 3471
245fc96e
MB
3472/* @returns 0 on success
3473 * -1 on error
3a46cf93 3474 * -2 if FR_RRB_PAIRWISE is missing
245fc96e
MB
3475 */
3476static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth,
3477 const u8 *src_addr, u8 type,
3478 const u8 *enc, size_t enc_len,
3479 const u8 *auth, size_t auth_len,
eefe8630
MB
3480 const char *msgtype, u8 *s1kh_id_out,
3481 int (*cb)(struct wpa_authenticator *wpa_auth,
3482 const u8 *src_addr,
3483 const u8 *enc, size_t enc_len,
3484 const u8 *auth, size_t auth_len,
3485 int no_defer))
245fc96e
MB
3486{
3487 u8 *plain = NULL;
3488 size_t plain_len = 0;
3a46cf93 3489 struct ft_remote_r0kh *r0kh, *r0kh_wildcard;
245fc96e
MB
3490 const u8 *key;
3491 size_t key_len;
eefe8630 3492 int seq_ret;
245fc96e
MB
3493 const u8 *f_r1kh_id, *f_s1kh_id, *f_r0kh_id;
3494 const u8 *f_pmk_r1_name, *f_pairwise, *f_pmk_r1;
3a3e2832 3495 const u8 *f_expires_in;
245fc96e 3496 size_t f_r1kh_id_len, f_s1kh_id_len, f_r0kh_id_len;
069b4e30 3497 const u8 *f_identity, *f_radius_cui;
a6509e85 3498 const u8 *f_session_timeout;
245fc96e 3499 size_t f_pmk_r1_name_len, f_pairwise_len, f_pmk_r1_len;
3a3e2832 3500 size_t f_expires_in_len;
069b4e30 3501 size_t f_identity_len, f_radius_cui_len;
a6509e85 3502 size_t f_session_timeout_len;
245fc96e
MB
3503 int pairwise;
3504 int ret = -1;
3a3e2832 3505 int expires_in;
a6509e85 3506 int session_timeout;
17010c38 3507 struct vlan_description vlan;
6fc6879b 3508
245fc96e
MB
3509 RRB_GET_AUTH(FT_RRB_R0KH_ID, r0kh_id, msgtype, -1);
3510 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID", f_r0kh_id, f_r0kh_id_len);
6fc6879b 3511
245fc96e
MB
3512 RRB_GET_AUTH(FT_RRB_R1KH_ID, r1kh_id, msgtype, FT_R1KH_ID_LEN);
3513 wpa_printf(MSG_DEBUG, "FT: R1KH-ID=" MACSTR, MAC2STR(f_r1kh_id));
3514
3515 if (wpa_ft_rrb_check_r1kh(wpa_auth, f_r1kh_id)) {
3516 wpa_printf(MSG_DEBUG, "FT: R1KH-ID mismatch");
3517 goto out;
6fc6879b
JM
3518 }
3519
3a46cf93
MB
3520 wpa_ft_rrb_lookup_r0kh(wpa_auth, f_r0kh_id, f_r0kh_id_len, &r0kh,
3521 &r0kh_wildcard);
3522 if (r0kh) {
3523 key = r0kh->key;
3524 key_len = sizeof(r0kh->key);
3525 } else if (r0kh_wildcard) {
3526 wpa_printf(MSG_DEBUG, "FT: Using wildcard R0KH-ID");
3527 key = r0kh_wildcard->key;
3528 key_len = sizeof(r0kh_wildcard->key);
3529 } else {
245fc96e 3530 goto out;
3a46cf93
MB
3531 }
3532
3533 seq_ret = FT_RRB_SEQ_DROP;
3534 if (r0kh) {
3535 seq_ret = wpa_ft_rrb_seq_chk(r0kh->seq, src_addr, enc, enc_len,
3536 auth, auth_len, msgtype,
3537 cb ? 0 : 1);
3538 }
3539 if (cb && r0kh_wildcard &&
3540 (!r0kh || os_memcmp(r0kh->addr, src_addr, ETH_ALEN) != 0)) {
3541 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3542 seq_ret = FT_RRB_SEQ_DEFER;
3543 }
6fc6879b 3544
eefe8630
MB
3545 if (seq_ret == FT_RRB_SEQ_DROP)
3546 goto out;
3547
245fc96e
MB
3548 if (wpa_ft_rrb_decrypt(key, key_len, enc, enc_len, auth, auth_len,
3549 src_addr, type, &plain, &plain_len) < 0)
3550 goto out;
3551
3a46cf93
MB
3552 if (!r0kh)
3553 r0kh = wpa_ft_rrb_add_r0kh(wpa_auth, r0kh_wildcard, src_addr,
3554 f_r0kh_id, f_r0kh_id_len,
3555 wpa_auth->conf.rkh_pos_timeout);
3556 if (!r0kh)
3557 goto out;
3558
eefe8630
MB
3559 if (seq_ret == FT_RRB_SEQ_DEFER) {
3560 wpa_ft_rrb_seq_req(wpa_auth, r0kh->seq, src_addr, f_r0kh_id,
3561 f_r0kh_id_len, f_r1kh_id, key, key_len,
3562 enc, enc_len, auth, auth_len, cb);
3563 goto out;
3564 }
3565
3566 wpa_ft_rrb_seq_accept(wpa_auth, r0kh->seq, src_addr, auth, auth_len,
3567 msgtype);
3a46cf93
MB
3568 wpa_ft_rrb_r0kh_replenish(wpa_auth, r0kh,
3569 wpa_auth->conf.rkh_pos_timeout);
eefe8630 3570
245fc96e
MB
3571 RRB_GET(FT_RRB_S1KH_ID, s1kh_id, msgtype, ETH_ALEN);
3572 wpa_printf(MSG_DEBUG, "FT: S1KH-ID=" MACSTR, MAC2STR(f_s1kh_id));
3573
3574 if (s1kh_id_out)
3575 os_memcpy(s1kh_id_out, f_s1kh_id, ETH_ALEN);
3576
3a46cf93 3577 ret = -2;
245fc96e
MB
3578 RRB_GET(FT_RRB_PAIRWISE, pairwise, msgtype, sizeof(le16));
3579 wpa_hexdump(MSG_DEBUG, "FT: pairwise", f_pairwise, f_pairwise_len);
3580
3a46cf93 3581 ret = -1;
245fc96e
MB
3582 RRB_GET(FT_RRB_PMK_R1_NAME, pmk_r1_name, msgtype, WPA_PMK_NAME_LEN);
3583 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name",
3584 f_pmk_r1_name, WPA_PMK_NAME_LEN);
3585
3586 RRB_GET(FT_RRB_PMK_R1, pmk_r1, msgtype, PMK_LEN);
3587 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f_pmk_r1, PMK_LEN);
3588
3589 pairwise = WPA_GET_LE16(f_pairwise);
3590
3a3e2832
MB
3591 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN, expires_in, msgtype,
3592 sizeof(le16));
3593 if (f_expires_in)
3594 expires_in = WPA_GET_LE16(f_expires_in);
3595 else
3596 expires_in = 0;
3597
3598 wpa_printf(MSG_DEBUG, "FT: PMK-R1 %s - expires_in=%d", msgtype,
3599 expires_in);
3600
17010c38
MB
3601 if (wpa_ft_rrb_get_tlv_vlan(plain, plain_len, &vlan) < 0) {
3602 wpa_printf(MSG_DEBUG, "FT: Cannot parse vlan");
3603 wpa_ft_rrb_dump(plain, plain_len);
3604 goto out;
3605 }
3606
3607 wpa_printf(MSG_DEBUG, "FT: vlan %d%s",
3608 le_to_host16(vlan.untagged), vlan.tagged[0] ? "+" : "");
3609
069b4e30
MB
3610 RRB_GET_OPTIONAL(FT_RRB_IDENTITY, identity, msgtype, -1);
3611 if (f_identity)
3612 wpa_hexdump_ascii(MSG_DEBUG, "FT: Identity", f_identity,
3613 f_identity_len);
3614
3615 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI, radius_cui, msgtype, -1);
3616 if (f_radius_cui)
3617 wpa_hexdump_ascii(MSG_DEBUG, "FT: CUI", f_radius_cui,
3618 f_radius_cui_len);
3619
a6509e85
MB
3620 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT, session_timeout, msgtype,
3621 sizeof(le32));
3622 if (f_session_timeout)
3623 session_timeout = WPA_GET_LE32(f_session_timeout);
3624 else
3625 session_timeout = 0;
3626 wpa_printf(MSG_DEBUG, "FT: session_timeout %d", session_timeout);
3627
a3e18dbb
JM
3628 if (wpa_ft_store_pmk_r1(wpa_auth, f_s1kh_id, f_pmk_r1, PMK_LEN,
3629 f_pmk_r1_name,
a6509e85
MB
3630 pairwise, &vlan, expires_in, session_timeout,
3631 f_identity, f_identity_len, f_radius_cui,
069b4e30 3632 f_radius_cui_len) < 0)
245fc96e
MB
3633 goto out;
3634
3635 ret = 0;
3636out:
3637 if (plain) {
3638 os_memset(plain, 0, plain_len);
3639 os_free(plain);
3640 }
3641
3642 return ret;
6fc6879b 3643
6fc6879b
JM
3644}
3645
3646
245fc96e 3647static void ft_finish_pull(struct wpa_state_machine *sm)
692ec305 3648{
692ec305
JM
3649 int res;
3650 u8 *resp_ies;
3651 size_t resp_ies_len;
3652 u16 status;
3653
3a46cf93
MB
3654 if (!sm->ft_pending_cb || !sm->ft_pending_req_ies)
3655 return;
3656
692ec305
JM
3657 res = wpa_ft_process_auth_req(sm, wpabuf_head(sm->ft_pending_req_ies),
3658 wpabuf_len(sm->ft_pending_req_ies),
3659 &resp_ies, &resp_ies_len);
3a46cf93
MB
3660 if (res < 0) {
3661 /* this loop is broken by ft_pending_pull_left_retries */
3662 wpa_printf(MSG_DEBUG,
3663 "FT: Callback postponed until response is available");
3664 return;
3665 }
692ec305
JM
3666 wpabuf_free(sm->ft_pending_req_ies);
3667 sm->ft_pending_req_ies = NULL;
692ec305
JM
3668 status = res;
3669 wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR
3670 " - status %u", MAC2STR(sm->addr), status);
3671
3672 sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr,
3673 sm->ft_pending_auth_transaction + 1, status,
3674 resp_ies, resp_ies_len);
3675 os_free(resp_ies);
3676}
3677
3678
245fc96e
MB
3679struct ft_get_sta_ctx {
3680 const u8 *nonce;
3681 const u8 *s1kh_id;
3682 struct wpa_state_machine *sm;
3683};
3684
3685
3686static int ft_get_sta_cb(struct wpa_state_machine *sm, void *ctx)
692ec305 3687{
245fc96e 3688 struct ft_get_sta_ctx *info = ctx;
692ec305 3689
245fc96e
MB
3690 if ((info->s1kh_id &&
3691 os_memcmp(info->s1kh_id, sm->addr, ETH_ALEN) != 0) ||
3692 os_memcmp(info->nonce, sm->ft_pending_pull_nonce,
3693 FT_RRB_NONCE_LEN) != 0 ||
a8e25dee 3694 sm->ft_pending_cb == NULL || sm->ft_pending_req_ies == NULL)
692ec305
JM
3695 return 0;
3696
245fc96e
MB
3697 info->sm = sm;
3698
692ec305
JM
3699 return 1;
3700}
3701
3702
6fc6879b
JM
3703static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
3704 const u8 *src_addr,
245fc96e 3705 const u8 *enc, size_t enc_len,
eefe8630
MB
3706 const u8 *auth, size_t auth_len,
3707 int no_defer)
6fc6879b 3708{
245fc96e 3709 const char *msgtype = "pull response";
3a46cf93 3710 int nak, ret = -1;
245fc96e
MB
3711 struct ft_get_sta_ctx ctx;
3712 u8 s1kh_id[ETH_ALEN];
3713 const u8 *f_nonce;
3714 size_t f_nonce_len;
6fc6879b
JM
3715
3716 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response");
3717
245fc96e
MB
3718 RRB_GET_AUTH(FT_RRB_NONCE, nonce, msgtype, FT_RRB_NONCE_LEN);
3719 wpa_hexdump(MSG_DEBUG, "FT: nonce", f_nonce, f_nonce_len);
6fc6879b 3720
245fc96e
MB
3721 os_memset(&ctx, 0, sizeof(ctx));
3722 ctx.nonce = f_nonce;
3723 if (!wpa_auth_for_each_sta(wpa_auth, ft_get_sta_cb, &ctx)) {
3724 /* nonce not found */
3725 wpa_printf(MSG_DEBUG, "FT: Invalid nonce");
6fc6879b
JM
3726 return -1;
3727 }
3728
245fc96e 3729 ret = wpa_ft_rrb_rx_r1(wpa_auth, src_addr, FT_PACKET_R0KH_R1KH_RESP,
eefe8630
MB
3730 enc, enc_len, auth, auth_len, msgtype, s1kh_id,
3731 no_defer ? NULL : &wpa_ft_rrb_rx_resp);
3a46cf93
MB
3732 if (ret == -2) {
3733 ret = 0;
3734 nak = 1;
3735 } else {
3736 nak = 0;
3737 }
245fc96e 3738 if (ret < 0)
6fc6879b 3739 return -1;
6fc6879b 3740
245fc96e
MB
3741 ctx.s1kh_id = s1kh_id;
3742 if (wpa_auth_for_each_sta(wpa_auth, ft_get_sta_cb, &ctx)) {
3743 wpa_printf(MSG_DEBUG,
3744 "FT: Response to a pending pull request for " MACSTR,
3745 MAC2STR(ctx.sm->addr));
3a46cf93
MB
3746 eloop_cancel_timeout(wpa_ft_expire_pull, ctx.sm, NULL);
3747 if (nak)
3748 ctx.sm->ft_pending_pull_left_retries = 0;
245fc96e 3749 ft_finish_pull(ctx.sm);
6fc6879b
JM
3750 }
3751
245fc96e
MB
3752out:
3753 return ret;
6fc6879b
JM
3754}
3755
3756
3757static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth,
3758 const u8 *src_addr,
245fc96e 3759 const u8 *enc, size_t enc_len,
eefe8630 3760 const u8 *auth, size_t auth_len, int no_defer)
6fc6879b 3761{
245fc96e 3762 const char *msgtype = "push";
6fc6879b
JM
3763
3764 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 push");
3765
eefe8630
MB
3766 if (wpa_ft_rrb_rx_r1(wpa_auth, src_addr, FT_PACKET_R0KH_R1KH_PUSH,
3767 enc, enc_len, auth, auth_len, msgtype, NULL,
3768 no_defer ? NULL : wpa_ft_rrb_rx_push) < 0)
6fc6879b 3769 return -1;
eefe8630
MB
3770
3771 return 0;
3772}
3773
3774
3775static int wpa_ft_rrb_rx_seq(struct wpa_authenticator *wpa_auth,
3776 const u8 *src_addr, int type,
3777 const u8 *enc, size_t enc_len,
3778 const u8 *auth, size_t auth_len,
3779 struct ft_remote_seq **rkh_seq,
3a46cf93
MB
3780 u8 **key, size_t *key_len,
3781 struct ft_remote_r0kh **r0kh_out,
3782 struct ft_remote_r1kh **r1kh_out,
3783 struct ft_remote_r0kh **r0kh_wildcard_out,
3784 struct ft_remote_r1kh **r1kh_wildcard_out)
eefe8630
MB
3785{
3786 struct ft_remote_r0kh *r0kh = NULL;
3787 struct ft_remote_r1kh *r1kh = NULL;
3788 const u8 *f_r0kh_id, *f_r1kh_id;
3789 size_t f_r0kh_id_len, f_r1kh_id_len;
3790 int to_r0kh, to_r1kh;
3791 u8 *plain = NULL;
3792 size_t plain_len = 0;
3a46cf93
MB
3793 struct ft_remote_r0kh *r0kh_wildcard;
3794 struct ft_remote_r1kh *r1kh_wildcard;
eefe8630
MB
3795
3796 RRB_GET_AUTH(FT_RRB_R0KH_ID, r0kh_id, "seq", -1);
3797 RRB_GET_AUTH(FT_RRB_R1KH_ID, r1kh_id, "seq", FT_R1KH_ID_LEN);
3798
3799 to_r0kh = !wpa_ft_rrb_check_r0kh(wpa_auth, f_r0kh_id, f_r0kh_id_len);
3800 to_r1kh = !wpa_ft_rrb_check_r1kh(wpa_auth, f_r1kh_id);
3801
3802 if (to_r0kh && to_r1kh) {
3803 wpa_printf(MSG_DEBUG, "FT: seq - local R0KH-ID and R1KH-ID");
3804 goto out;
6fc6879b
JM
3805 }
3806
eefe8630
MB
3807 if (!to_r0kh && !to_r1kh) {
3808 wpa_printf(MSG_DEBUG, "FT: seq - remote R0KH-ID and R1KH-ID");
3809 goto out;
3810 }
3811
3812 if (!to_r0kh) {
3813 wpa_ft_rrb_lookup_r0kh(wpa_auth, f_r0kh_id, f_r0kh_id_len,
3a46cf93
MB
3814 &r0kh, &r0kh_wildcard);
3815 if (!r0kh_wildcard &&
3816 (!r0kh || os_memcmp(r0kh->addr, src_addr, ETH_ALEN) != 0)) {
eefe8630
MB
3817 wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID",
3818 f_r0kh_id, f_r0kh_id_len);
3819 goto out;
3820 }
3a46cf93
MB
3821 if (r0kh) {
3822 *key = r0kh->key;
3823 *key_len = sizeof(r0kh->key);
3824 } else {
3825 *key = r0kh_wildcard->key;
3826 *key_len = sizeof(r0kh_wildcard->key);
3827 }
eefe8630
MB
3828 }
3829
3830 if (!to_r1kh) {
3a46cf93
MB
3831 wpa_ft_rrb_lookup_r1kh(wpa_auth, f_r1kh_id, &r1kh,
3832 &r1kh_wildcard);
3833 if (!r1kh_wildcard &&
3834 (!r1kh || os_memcmp(r1kh->addr, src_addr, ETH_ALEN) != 0)) {
eefe8630
MB
3835 wpa_hexdump(MSG_DEBUG, "FT: Did not find R1KH-ID",
3836 f_r1kh_id, FT_R1KH_ID_LEN);
3837 goto out;
3838 }
3a46cf93
MB
3839 if (r1kh) {
3840 *key = r1kh->key;
3841 *key_len = sizeof(r1kh->key);
3842 } else {
3843 *key = r1kh_wildcard->key;
3844 *key_len = sizeof(r1kh_wildcard->key);
3845 }
eefe8630
MB
3846 }
3847
3848 if (wpa_ft_rrb_decrypt(*key, *key_len, enc, enc_len, auth, auth_len,
3849 src_addr, type, &plain, &plain_len) < 0)
3850 goto out;
3851
3852 os_free(plain);
3853
3a46cf93
MB
3854 if (!to_r0kh) {
3855 if (!r0kh)
3856 r0kh = wpa_ft_rrb_add_r0kh(wpa_auth, r0kh_wildcard,
3857 src_addr, f_r0kh_id,
3858 f_r0kh_id_len,
3859 ftRRBseqTimeout);
3860 if (!r0kh)
3861 goto out;
3862
3863 wpa_ft_rrb_r0kh_replenish(wpa_auth, r0kh, ftRRBseqTimeout);
3864 *rkh_seq = r0kh->seq;
3865 if (r0kh_out)
3866 *r0kh_out = r0kh;
3867 if (r0kh_wildcard_out)
3868 *r0kh_wildcard_out = r0kh_wildcard;
3869 }
3870
3871 if (!to_r1kh) {
3872 if (!r1kh)
3873 r1kh = wpa_ft_rrb_add_r1kh(wpa_auth, r1kh_wildcard,
3874 src_addr, f_r1kh_id,
3875 ftRRBseqTimeout);
3876 if (!r1kh)
3877 goto out;
3878
3879 wpa_ft_rrb_r1kh_replenish(wpa_auth, r1kh, ftRRBseqTimeout);
3880 *rkh_seq = r1kh->seq;
3881 if (r1kh_out)
3882 *r1kh_out = r1kh;
3883 if (r1kh_wildcard_out)
3884 *r1kh_wildcard_out = r1kh_wildcard;
3885 }
3886
eefe8630
MB
3887 return 0;
3888out:
3889 return -1;
3890}
3891
3892
3893static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator *wpa_auth,
3894 const u8 *src_addr,
3895 const u8 *enc, size_t enc_len,
3896 const u8 *auth, size_t auth_len,
3897 int no_defer)
3898{
3899 int ret = -1;
3900 struct ft_rrb_seq f_seq;
3901 const u8 *f_nonce, *f_r0kh_id, *f_r1kh_id;
3902 size_t f_nonce_len, f_r0kh_id_len, f_r1kh_id_len;
3a46cf93 3903 struct ft_remote_seq *rkh_seq = NULL;
eefe8630
MB
3904 u8 *packet = NULL, *key = NULL;
3905 size_t packet_len = 0, key_len = 0;
3906 struct tlv_list seq_resp_auth[5];
3907
3908 wpa_printf(MSG_DEBUG, "FT: Received sequence number request");
3909
3910 if (wpa_ft_rrb_rx_seq(wpa_auth, src_addr, FT_PACKET_R0KH_R1KH_SEQ_REQ,
3911 enc, enc_len, auth, auth_len, &rkh_seq, &key,
3a46cf93 3912 &key_len, NULL, NULL, NULL, NULL) < 0)
eefe8630
MB
3913 goto out;
3914
3915 RRB_GET_AUTH(FT_RRB_NONCE, nonce, "seq request", FT_RRB_NONCE_LEN);
3916 wpa_hexdump(MSG_DEBUG, "FT: seq request - nonce", f_nonce, f_nonce_len);
3917
3918 RRB_GET_AUTH(FT_RRB_R0KH_ID, r0kh_id, "seq", -1);
3919 RRB_GET_AUTH(FT_RRB_R1KH_ID, r1kh_id, "seq", FT_R1KH_ID_LEN);
3920
3921 if (wpa_ft_new_seq(rkh_seq, &f_seq) < 0) {
3922 wpa_printf(MSG_DEBUG, "FT: Failed to get seq num");
3923 goto out;
3924 }
3925
3926 seq_resp_auth[0].type = FT_RRB_NONCE;
3927 seq_resp_auth[0].len = f_nonce_len;
3928 seq_resp_auth[0].data = f_nonce;
3929 seq_resp_auth[1].type = FT_RRB_SEQ;
3930 seq_resp_auth[1].len = sizeof(f_seq);
3931 seq_resp_auth[1].data = (u8 *) &f_seq;
3932 seq_resp_auth[2].type = FT_RRB_R0KH_ID;
3933 seq_resp_auth[2].len = f_r0kh_id_len;
3934 seq_resp_auth[2].data = f_r0kh_id;
3935 seq_resp_auth[3].type = FT_RRB_R1KH_ID;
3936 seq_resp_auth[3].len = FT_R1KH_ID_LEN;
3937 seq_resp_auth[3].data = f_r1kh_id;
3938 seq_resp_auth[4].type = FT_RRB_LAST_EMPTY;
3939 seq_resp_auth[4].len = 0;
3940 seq_resp_auth[4].data = NULL;
3941
17010c38 3942 if (wpa_ft_rrb_build(key, key_len, NULL, NULL, seq_resp_auth, NULL,
eefe8630
MB
3943 wpa_auth->addr, FT_PACKET_R0KH_R1KH_SEQ_RESP,
3944 &packet, &packet_len) < 0)
3945 goto out;
3946
3947 wpa_ft_rrb_oui_send(wpa_auth, src_addr,
3948 FT_PACKET_R0KH_R1KH_SEQ_RESP, packet,
3949 packet_len);
3950
3951out:
3952 os_free(packet);
3953
3954 return ret;
3955}
3956
3957
3958static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator *wpa_auth,
3959 const u8 *src_addr,
3960 const u8 *enc, size_t enc_len,
3961 const u8 *auth, size_t auth_len,
3962 int no_defer)
3963{
3964 u8 *key = NULL;
3965 size_t key_len = 0;
3a46cf93
MB
3966 struct ft_remote_r0kh *r0kh = NULL, *r0kh_wildcard = NULL;
3967 struct ft_remote_r1kh *r1kh = NULL, *r1kh_wildcard = NULL;
eefe8630
MB
3968 const u8 *f_nonce, *f_seq;
3969 size_t f_nonce_len, f_seq_len;
3970 struct ft_remote_seq *rkh_seq = NULL;
3971 struct ft_remote_item *item;
3972 struct os_reltime now, now_remote;
3973 int seq_ret, found;
3974 const struct ft_rrb_seq *msg_both;
3975 u32 msg_dom, msg_seq;
3976
3977 wpa_printf(MSG_DEBUG, "FT: Received sequence number response");
3978
3979 if (wpa_ft_rrb_rx_seq(wpa_auth, src_addr, FT_PACKET_R0KH_R1KH_SEQ_RESP,
3980 enc, enc_len, auth, auth_len, &rkh_seq, &key,
3a46cf93
MB
3981 &key_len, &r0kh, &r1kh, &r0kh_wildcard,
3982 &r1kh_wildcard) < 0)
eefe8630
MB
3983 goto out;
3984
3985 RRB_GET_AUTH(FT_RRB_NONCE, nonce, "seq response", FT_RRB_NONCE_LEN);
3986 wpa_hexdump(MSG_DEBUG, "FT: seq response - nonce", f_nonce,
3987 f_nonce_len);
3988
3989 found = 0;
3990 dl_list_for_each(item, &rkh_seq->rx.queue, struct ft_remote_item,
3991 list) {
3992 if (os_memcmp_const(f_nonce, item->nonce,
3993 FT_RRB_NONCE_LEN) != 0 ||
3994 os_get_reltime(&now) < 0 ||
3995 os_reltime_expired(&now, &item->nonce_ts, ftRRBseqTimeout))
3996 continue;
3997
3998 found = 1;
3999 break;
4000 }
4001 if (!found) {
4002 wpa_printf(MSG_DEBUG, "FT: seq response - bad nonce");
4003 goto out;
4004 }
4005
3a46cf93
MB
4006 if (r0kh) {
4007 wpa_ft_rrb_r0kh_replenish(wpa_auth, r0kh,
4008 wpa_auth->conf.rkh_pos_timeout);
4009 if (r0kh_wildcard)
4010 os_memcpy(r0kh->addr, src_addr, ETH_ALEN);
4011 }
4012
4013 if (r1kh) {
4014 wpa_ft_rrb_r1kh_replenish(wpa_auth, r1kh,
4015 wpa_auth->conf.rkh_pos_timeout);
4016 if (r1kh_wildcard)
4017 os_memcpy(r1kh->addr, src_addr, ETH_ALEN);
4018 }
4019
eefe8630
MB
4020 seq_ret = wpa_ft_rrb_seq_chk(rkh_seq, src_addr, enc, enc_len, auth,
4021 auth_len, "seq response", 1);
4022 if (seq_ret == FT_RRB_SEQ_OK) {
4023 wpa_printf(MSG_DEBUG, "FT: seq response - valid seq number");
4024 wpa_ft_rrb_seq_accept(wpa_auth, rkh_seq, src_addr, auth,
4025 auth_len, "seq response");
4026 } else {
4027 wpa_printf(MSG_DEBUG, "FT: seq response - reset seq number");
4028
4029 RRB_GET_AUTH(FT_RRB_SEQ, seq, "seq response",
4030 sizeof(*msg_both));
4031 msg_both = (const struct ft_rrb_seq *) f_seq;
4032
4033 msg_dom = le_to_host32(msg_both->dom);
4034 msg_seq = le_to_host32(msg_both->seq);
4035 now_remote.sec = le_to_host32(msg_both->ts);
4036 now_remote.usec = 0;
4037
4038 rkh_seq->rx.num_last = 2;
4039 rkh_seq->rx.dom = msg_dom;
4040 rkh_seq->rx.offsetidx = 0;
4041 /* Accept some older, possibly cached packets as well */
4042 rkh_seq->rx.last[0] = msg_seq - FT_REMOTE_SEQ_BACKLOG -
4043 dl_list_len(&rkh_seq->rx.queue);
4044 rkh_seq->rx.last[1] = msg_seq;
4045
4046 /* local time - offset = remote time
4047 * <=> local time - remote time = offset */
4048 os_reltime_sub(&now, &now_remote, &rkh_seq->rx.time_offset);
4049 }
4050
4051 wpa_ft_rrb_seq_flush(wpa_auth, rkh_seq, 1);
6fc6879b
JM
4052
4053 return 0;
245fc96e
MB
4054out:
4055 return -1;
6fc6879b
JM
4056}
4057
4058
4059int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
4060 const u8 *data, size_t data_len)
4061{
4062 struct ft_rrb_frame *frame;
4063 u16 alen;
4064 const u8 *pos, *end, *start;
4065 u8 action;
4066 const u8 *sta_addr, *target_ap_addr;
4067
4068 wpa_printf(MSG_DEBUG, "FT: RRB received frame from remote AP " MACSTR,
4069 MAC2STR(src_addr));
4070
4071 if (data_len < sizeof(*frame)) {
4072 wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (data_len=%lu)",
4073 (unsigned long) data_len);
4074 return -1;
4075 }
4076
4077 pos = data;
4078 frame = (struct ft_rrb_frame *) pos;
4079 pos += sizeof(*frame);
4080
4081 alen = le_to_host16(frame->action_length);
4082 wpa_printf(MSG_DEBUG, "FT: RRB frame - frame_type=%d packet_type=%d "
4083 "action_length=%d ap_address=" MACSTR,
4084 frame->frame_type, frame->packet_type, alen,
4085 MAC2STR(frame->ap_address));
4086
4087 if (frame->frame_type != RSN_REMOTE_FRAME_TYPE_FT_RRB) {
c1e033b0 4088 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
6fc6879b
JM
4089 wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with "
4090 "unrecognized type %d", frame->frame_type);
4091 return -1;
4092 }
4093
4094 if (alen > data_len - sizeof(*frame)) {
4095 wpa_printf(MSG_DEBUG, "FT: RRB frame too short for action "
4096 "frame");
4097 return -1;
4098 }
4099
6fc6879b
JM
4100 wpa_hexdump(MSG_MSGDUMP, "FT: RRB - FT Action frame", pos, alen);
4101
4102 if (alen < 1 + 1 + 2 * ETH_ALEN) {
4103 wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (not enough "
4104 "room for Action Frame body); alen=%lu",
4105 (unsigned long) alen);
4106 return -1;
4107 }
4108 start = pos;
4109 end = pos + alen;
4110
4111 if (*pos != WLAN_ACTION_FT) {
4112 wpa_printf(MSG_DEBUG, "FT: Unexpected Action frame category "
4113 "%d", *pos);
4114 return -1;
4115 }
4116
4117 pos++;
4118 action = *pos++;
4119 sta_addr = pos;
4120 pos += ETH_ALEN;
4121 target_ap_addr = pos;
4122 pos += ETH_ALEN;
4123 wpa_printf(MSG_DEBUG, "FT: RRB Action Frame: action=%d sta_addr="
4124 MACSTR " target_ap_addr=" MACSTR,
4125 action, MAC2STR(sta_addr), MAC2STR(target_ap_addr));
4126
4127 if (frame->packet_type == FT_PACKET_REQUEST) {
4128 wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Request");
4129
4130 if (action != 1) {
4131 wpa_printf(MSG_DEBUG, "FT: Unexpected Action %d in "
4132 "RRB Request", action);
4133 return -1;
4134 }
4135
4136 if (os_memcmp(target_ap_addr, wpa_auth->addr, ETH_ALEN) != 0) {
4137 wpa_printf(MSG_DEBUG, "FT: Target AP address in the "
4138 "RRB Request does not match with own "
4139 "address");
4140 return -1;
4141 }
4142
4143 if (wpa_ft_rrb_rx_request(wpa_auth, frame->ap_address,
4144 sta_addr, pos, end - pos) < 0)
4145 return -1;
4146 } else if (frame->packet_type == FT_PACKET_RESPONSE) {
4147 u16 status_code;
4148
4149 if (end - pos < 2) {
4150 wpa_printf(MSG_DEBUG, "FT: Not enough room for status "
4151 "code in RRB Response");
4152 return -1;
4153 }
4154 status_code = WPA_GET_LE16(pos);
4155 pos += 2;
4156
4157 wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response "
4158 "(status_code=%d)", status_code);
4159
4160 if (wpa_ft_action_send(wpa_auth, sta_addr, start, alen) < 0)
4161 return -1;
4162 } else {
4163 wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with unknown "
4164 "packet_type %d", frame->packet_type);
4165 return -1;
4166 }
4167
164a453f
JM
4168 if (end > pos) {
4169 wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end",
4170 pos, end - pos);
4171 }
4172
6fc6879b
JM
4173 return 0;
4174}
4175
4176
50bd8e0a
MB
4177void wpa_ft_rrb_oui_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
4178 const u8 *dst_addr, u8 oui_suffix, const u8 *data,
4179 size_t data_len)
4180{
245fc96e
MB
4181 const u8 *auth, *enc;
4182 size_t alen, elen;
3a46cf93 4183 int no_defer = 0;
245fc96e 4184
50bd8e0a
MB
4185 wpa_printf(MSG_DEBUG, "FT: RRB-OUI received frame from remote AP "
4186 MACSTR, MAC2STR(src_addr));
4187 wpa_printf(MSG_DEBUG, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix);
4188
4189 if (is_multicast_ether_addr(src_addr)) {
4190 wpa_printf(MSG_DEBUG,
4191 "FT: RRB-OUI received frame from multicast address "
4192 MACSTR, MAC2STR(src_addr));
4193 return;
4194 }
4195
4196 if (is_multicast_ether_addr(dst_addr)) {
4197 wpa_printf(MSG_DEBUG,
4198 "FT: RRB-OUI received frame from remote AP " MACSTR
4199 " to multicast address " MACSTR,
4200 MAC2STR(src_addr), MAC2STR(dst_addr));
3a46cf93 4201 no_defer = 1;
50bd8e0a
MB
4202 }
4203
245fc96e
MB
4204 if (data_len < sizeof(u16)) {
4205 wpa_printf(MSG_DEBUG, "FT: RRB-OUI frame too short");
4206 return;
4207 }
4208
4209 alen = WPA_GET_LE16(data);
4210 if (data_len < sizeof(u16) + alen) {
4211 wpa_printf(MSG_DEBUG, "FT: RRB-OUI frame too short");
4212 return;
4213 }
4214
4215 auth = data + sizeof(u16);
4216 enc = data + sizeof(u16) + alen;
4217 elen = data_len - sizeof(u16) - alen;
4218
50bd8e0a
MB
4219 switch (oui_suffix) {
4220 case FT_PACKET_R0KH_R1KH_PULL:
eefe8630 4221 wpa_ft_rrb_rx_pull(wpa_auth, src_addr, enc, elen, auth, alen,
3a46cf93 4222 no_defer);
50bd8e0a
MB
4223 break;
4224 case FT_PACKET_R0KH_R1KH_RESP:
eefe8630 4225 wpa_ft_rrb_rx_resp(wpa_auth, src_addr, enc, elen, auth, alen,
3a46cf93 4226 no_defer);
50bd8e0a
MB
4227 break;
4228 case FT_PACKET_R0KH_R1KH_PUSH:
eefe8630 4229 wpa_ft_rrb_rx_push(wpa_auth, src_addr, enc, elen, auth, alen,
3a46cf93 4230 no_defer);
eefe8630
MB
4231 break;
4232 case FT_PACKET_R0KH_R1KH_SEQ_REQ:
4233 wpa_ft_rrb_rx_seq_req(wpa_auth, src_addr, enc, elen, auth, alen,
3a46cf93 4234 no_defer);
eefe8630
MB
4235 break;
4236 case FT_PACKET_R0KH_R1KH_SEQ_RESP:
4237 wpa_ft_rrb_rx_seq_resp(wpa_auth, src_addr, enc, elen, auth,
3a46cf93 4238 alen, no_defer);
50bd8e0a
MB
4239 break;
4240 }
4241}
4242
4243
364c064a
JM
4244static int wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
4245 struct wpa_ft_pmk_r0_sa *pmk_r0,
4246 struct ft_remote_r1kh *r1kh,
245fc96e 4247 const u8 *s1kh_id)
6fc6879b 4248{
245fc96e
MB
4249 u8 *packet;
4250 size_t packet_len;
eefe8630 4251 struct ft_rrb_seq f_seq;
245fc96e
MB
4252 struct tlv_list push[] = {
4253 { .type = FT_RRB_S1KH_ID, .len = ETH_ALEN,
4254 .data = s1kh_id },
4255 { .type = FT_RRB_PMK_R0_NAME, .len = WPA_PMK_NAME_LEN,
4256 .data = pmk_r0->pmk_r0_name },
4257 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
4258 };
4259 struct tlv_list push_auth[] = {
eefe8630
MB
4260 { .type = FT_RRB_SEQ, .len = sizeof(f_seq),
4261 .data = (u8 *) &f_seq },
245fc96e
MB
4262 { .type = FT_RRB_R0KH_ID,
4263 .len = wpa_auth->conf.r0_key_holder_len,
4264 .data = wpa_auth->conf.r0_key_holder },
4265 { .type = FT_RRB_R1KH_ID, .len = FT_R1KH_ID_LEN,
4266 .data = r1kh->id },
4267 { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL },
4268 };
4269
eefe8630
MB
4270 if (wpa_ft_new_seq(r1kh->seq, &f_seq) < 0) {
4271 wpa_printf(MSG_DEBUG, "FT: Failed to get seq num");
4272 return -1;
4273 }
245fc96e
MB
4274
4275 if (wpa_ft_rrb_build_r0(r1kh->key, sizeof(r1kh->key), push, pmk_r0,
4276 r1kh->id, s1kh_id, push_auth, wpa_auth->addr,
4277 FT_PACKET_R0KH_R1KH_PUSH,
4278 &packet, &packet_len) < 0)
364c064a 4279 return -1;
6fc6879b 4280
50bd8e0a 4281 wpa_ft_rrb_oui_send(wpa_auth, r1kh->addr, FT_PACKET_R0KH_R1KH_PUSH,
245fc96e
MB
4282 packet, packet_len);
4283
4284 os_free(packet);
364c064a 4285 return 0;
6fc6879b
JM
4286}
4287
4288
4289void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr)
4290{
09211c98
MB
4291 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
4292 struct wpa_ft_pmk_r0_sa *r0, *r0found = NULL;
6fc6879b
JM
4293 struct ft_remote_r1kh *r1kh;
4294
4295 if (!wpa_auth->conf.pmk_r1_push)
4296 return;
3a46cf93
MB
4297 if (!wpa_auth->conf.r1kh_list)
4298 return;
6fc6879b 4299
09211c98
MB
4300 dl_list_for_each(r0, &cache->pmk_r0, struct wpa_ft_pmk_r0_sa, list) {
4301 if (os_memcmp(r0->spa, addr, ETH_ALEN) == 0) {
4302 r0found = r0;
6fc6879b 4303 break;
09211c98 4304 }
6fc6879b
JM
4305 }
4306
09211c98 4307 r0 = r0found;
6fc6879b
JM
4308 if (r0 == NULL || r0->pmk_r1_pushed)
4309 return;
4310 r0->pmk_r1_pushed = 1;
4311
4312 wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4313 "for STA " MACSTR, MAC2STR(addr));
4314
3a46cf93
MB
4315 for (r1kh = *wpa_auth->conf.r1kh_list; r1kh; r1kh = r1kh->next) {
4316 if (is_zero_ether_addr(r1kh->addr) ||
4317 is_zero_ether_addr(r1kh->id))
4318 continue;
eefe8630
MB
4319 if (wpa_ft_rrb_init_r1kh_seq(r1kh) < 0)
4320 continue;
245fc96e 4321 wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr);
6fc6879b
JM
4322 }
4323}
4324
4ec1fd8e 4325#endif /* CONFIG_IEEE80211R_AP */