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