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