2 * hostapd - IEEE 802.11r - Fast BSS Transition
3 * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "utils/list.h"
14 #include "common/ieee802_11_defs.h"
15 #include "common/ieee802_11_common.h"
16 #include "crypto/aes.h"
17 #include "crypto/aes_siv.h"
18 #include "crypto/aes_wrap.h"
19 #include "crypto/random.h"
20 #include "ap_config.h"
21 #include "ieee802_11.h"
24 #include "wpa_auth_i.h"
27 #ifdef CONFIG_IEEE80211R_AP
29 const unsigned int ftRRBseqTimeout
= 10;
30 const unsigned int ftRRBmaxQueueLen
= 100;
33 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
34 const u8
*current_ap
, const u8
*sta_addr
,
35 u16 status
, const u8
*resp_ies
,
37 static void ft_finish_pull(struct wpa_state_machine
*sm
);
38 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
39 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
49 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
50 * @key: AES-SIV key for AEAD
51 * @key_len: Length of key in octets
52 * @enc: Pointer to encrypted TLVs
53 * @enc_len: Length of encrypted TLVs in octets
54 * @auth: Pointer to authenticated TLVs
55 * @auth_len: Length of authenticated TLVs in octets
56 * @src_addr: MAC address of the frame sender
57 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
58 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
59 * needs to be freed by the caller if not NULL;
60 * will only be returned on success
61 * @plain_len: Pointer to return the length of the allocated plaintext buffer
63 * Returns: 0 on success, -1 on error
65 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
66 const u8
*enc
, const size_t enc_len
,
67 const u8
*auth
, const size_t auth_len
,
68 const u8
*src_addr
, u8 type
,
69 u8
**plain
, size_t *plain_size
)
71 const u8
*ad
[3] = { src_addr
, auth
, &type
};
72 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
74 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
76 if (!key
) { /* skip decryption */
77 *plain
= os_memdup(enc
, enc_len
);
78 if (enc_len
> 0 && !*plain
)
81 *plain_size
= enc_len
;
89 if (enc_len
< AES_BLOCK_SIZE
)
92 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
96 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
100 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
101 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
102 *plain
, *plain_size
);
109 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
115 /* get first tlv record in packet matching type
116 * @data (decrypted) packet
117 * @return 0 on success else -1
119 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
120 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
122 const struct ft_rrb_tlv
*f
;
128 type16
= host_to_le16(type
);
130 while (left
>= sizeof(*f
)) {
131 f
= (const struct ft_rrb_tlv
*) plain
;
135 len
= le_to_host16(f
->len
);
138 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
142 if (f
->type
== type16
) {
156 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
158 const struct ft_rrb_tlv
*f
;
164 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
165 while (left
>= sizeof(*f
)) {
166 f
= (const struct ft_rrb_tlv
*) plain
;
170 len
= le_to_host16(f
->len
);
172 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
173 le_to_host16(f
->type
), len
);
176 wpa_printf(MSG_DEBUG
,
177 "FT: RRB message truncated: left %zu bytes, need %zu",
182 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
189 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
191 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
195 static int cmp_int(const void *a
, const void *b
)
205 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
206 struct vlan_description
*vlan
)
208 struct ft_rrb_tlv
*f
;
217 os_memset(vlan
, 0, sizeof(*vlan
));
219 while (left
>= sizeof(*f
)) {
220 f
= (struct ft_rrb_tlv
*) plain
;
225 len
= le_to_host16(f
->len
);
226 type
= le_to_host16(f
->type
);
229 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
233 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
236 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
237 wpa_printf(MSG_DEBUG
,
238 "FT: RRB VLAN_UNTAGGED invalid length");
242 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
243 wpa_printf(MSG_DEBUG
,
244 "FT: RRB VLAN_TAGGED invalid length");
248 while (len
>= sizeof(le16
)) {
249 vlan_id
= WPA_GET_LE16(plain
);
250 plain
+= sizeof(le16
);
251 left
-= sizeof(le16
);
254 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
255 wpa_printf(MSG_DEBUG
,
256 "FT: RRB VLAN ID invalid %d",
261 if (type
== FT_RRB_VLAN_UNTAGGED
)
262 vlan
->untagged
= vlan_id
;
264 if (type
== FT_RRB_VLAN_TAGGED
&&
265 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
266 vlan
->tagged
[taggedidx
] = vlan_id
;
268 } else if (type
== FT_RRB_VLAN_TAGGED
) {
269 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
279 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
281 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
287 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
295 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
296 tlv_len
+= sizeof(struct ft_rrb_tlv
);
297 tlv_len
+= tlvs
[i
].len
;
304 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
309 struct ft_rrb_tlv
*hdr
;
317 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
318 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
320 tlv_len
+= sizeof(*hdr
);
321 hdr
= (struct ft_rrb_tlv
*) pos
;
322 hdr
->type
= host_to_le16(tlvs
[i
].type
);
323 hdr
->len
= host_to_le16(tlvs
[i
].len
);
324 pos
= start
+ tlv_len
;
326 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
328 tlv_len
+= tlvs
[i
].len
;
329 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
330 pos
= start
+ tlv_len
;
337 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
342 if (!vlan
|| !vlan
->notempty
)
345 if (vlan
->untagged
) {
346 tlv_len
+= sizeof(struct ft_rrb_tlv
);
347 tlv_len
+= sizeof(le16
);
350 tlv_len
+= sizeof(struct ft_rrb_tlv
);
351 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
352 tlv_len
+= sizeof(le16
);
358 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
359 u8
*start
, u8
*endpos
)
363 struct ft_rrb_tlv
*hdr
;
366 if (!vlan
|| !vlan
->notempty
)
370 if (vlan
->untagged
) {
371 tlv_len
+= sizeof(*hdr
);
372 if (start
+ tlv_len
> endpos
)
374 hdr
= (struct ft_rrb_tlv
*) pos
;
375 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
376 hdr
->len
= host_to_le16(sizeof(le16
));
377 pos
= start
+ tlv_len
;
379 tlv_len
+= sizeof(le16
);
380 if (start
+ tlv_len
> endpos
)
382 WPA_PUT_LE16(pos
, vlan
->untagged
);
383 pos
= start
+ tlv_len
;
386 if (!vlan
->tagged
[0])
389 tlv_len
+= sizeof(*hdr
);
390 if (start
+ tlv_len
> endpos
)
392 hdr
= (struct ft_rrb_tlv
*) pos
;
393 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
394 len
= 0; /* len is computed below */
395 pos
= start
+ tlv_len
;
397 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
398 tlv_len
+= sizeof(le16
);
399 if (start
+ tlv_len
> endpos
)
402 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
403 pos
= start
+ tlv_len
;
406 hdr
->len
= host_to_le16(len
);
412 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
413 const struct tlv_list
*tlvs2
,
414 const struct vlan_description
*vlan
,
415 u8
**plain
, size_t *plain_len
)
420 tlv_len
= wpa_ft_tlv_len(tlvs1
);
421 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
422 tlv_len
+= wpa_ft_vlan_len(vlan
);
424 *plain_len
= tlv_len
;
425 *plain
= os_zalloc(tlv_len
);
427 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
432 endpos
= *plain
+ tlv_len
;
433 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
434 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
435 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
439 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
453 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
454 const u8
*plain
, const size_t plain_len
,
455 const u8
*auth
, const size_t auth_len
,
456 const u8
*src_addr
, u8 type
, u8
*enc
)
458 const u8
*ad
[3] = { src_addr
, auth
, &type
};
459 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
461 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
463 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
466 /* encryption not needed, return plaintext as packet */
467 os_memcpy(enc
, plain
, plain_len
);
468 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
469 3, ad
, ad_len
, enc
) < 0) {
470 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
479 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
480 * @key: AES-SIV key for AEAD
481 * @key_len: Length of key in octets
482 * @tlvs_enc0: First set of to-be-encrypted TLVs
483 * @tlvs_enc1: Second set of to-be-encrypted TLVs
484 * @tlvs_auth: Set of to-be-authenticated TLVs
485 * @src_addr: MAC address of the frame sender
486 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
487 * @packet Pointer to return the pointer to the allocated packet buffer;
488 * needs to be freed by the caller if not null;
489 * will only be returned on success
490 * @packet_len: Pointer to return the length of the allocated buffer in octets
491 * Returns: 0 on success, -1 on error
493 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
494 const struct tlv_list
*tlvs_enc0
,
495 const struct tlv_list
*tlvs_enc1
,
496 const struct tlv_list
*tlvs_auth
,
497 const struct vlan_description
*vlan
,
498 const u8
*src_addr
, u8 type
,
499 u8
**packet
, size_t *packet_len
)
501 u8
*plain
= NULL
, *auth
= NULL
, *pos
;
502 size_t plain_len
= 0, auth_len
= 0;
505 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
508 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
511 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
513 *packet_len
+= AES_BLOCK_SIZE
;
514 *packet
= os_zalloc(*packet_len
);
519 WPA_PUT_LE16(pos
, auth_len
);
521 os_memcpy(pos
, auth
, auth_len
);
523 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
524 auth_len
, src_addr
, type
, pos
) < 0)
530 bin_clear_free(plain
, plain_len
);
534 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
544 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
545 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
546 &f_##field##_len, &f_##field) < 0 || \
547 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
548 wpa_printf(MSG_INFO, "FT: Missing required " #field \
549 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
550 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
555 #define RRB_GET(type, field, txt, checklength) \
556 RRB_GET_SRC(plain, type, field, txt, checklength)
557 #define RRB_GET_AUTH(type, field, txt, checklength) \
558 RRB_GET_SRC(auth, type, field, txt, checklength)
560 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
561 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
562 &f_##field##_len, &f_##field) < 0 || \
563 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
564 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
565 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
566 f_##field##_len = 0; \
571 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
572 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
573 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
574 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
576 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
577 const u8
*data
, size_t data_len
)
579 if (wpa_auth
->cb
->send_ether
== NULL
)
581 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
582 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
587 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
588 const u8
*dst
, u8 oui_suffix
,
589 const u8
*data
, size_t data_len
)
591 if (!wpa_auth
->cb
->send_oui
)
593 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
,
594 oui_suffix
, MAC2STR(dst
));
595 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
600 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
601 const u8
*dst
, const u8
*data
, size_t data_len
)
603 if (wpa_auth
->cb
->send_ft_action
== NULL
)
605 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
610 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
611 const u8
*addr
, const u8
*p2p_dev_addr
,
614 if (wpa_auth
->cb
->get_psk
== NULL
)
616 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
621 static struct wpa_state_machine
*
622 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
624 if (wpa_auth
->cb
->add_sta
== NULL
)
626 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
630 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
631 const u8
*sta_addr
, struct vlan_description
*vlan
)
633 if (!wpa_auth
->cb
->set_vlan
)
635 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
639 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
640 const u8
*sta_addr
, struct vlan_description
*vlan
)
642 if (!wpa_auth
->cb
->get_vlan
)
644 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
648 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
650 u8
*tspec_ie
, size_t tspec_ielen
)
652 if (wpa_auth
->cb
->add_tspec
== NULL
) {
653 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
656 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
661 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
665 if (len
< 2 + sizeof(struct rsn_mdie
))
668 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
669 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
670 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
671 pos
+= MOBILITY_DOMAIN_ID_LEN
;
673 if (conf
->ft_over_ds
)
674 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
681 int wpa_write_ftie(struct wpa_auth_config
*conf
, const u8
*r0kh_id
,
683 const u8
*anonce
, const u8
*snonce
,
684 u8
*buf
, size_t len
, const u8
*subelem
,
687 u8
*pos
= buf
, *ielen
;
688 struct rsn_ftie
*hdr
;
690 if (len
< 2 + sizeof(*hdr
) + 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
694 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
697 hdr
= (struct rsn_ftie
*) pos
;
698 os_memset(hdr
, 0, sizeof(*hdr
));
700 WPA_PUT_LE16(hdr
->mic_control
, 0);
702 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
704 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
706 /* Optional Parameters */
707 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
708 *pos
++ = FT_R1KH_ID_LEN
;
709 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
710 pos
+= FT_R1KH_ID_LEN
;
713 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
714 *pos
++ = r0kh_id_len
;
715 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
720 os_memcpy(pos
, subelem
, subelem_len
);
724 *ielen
= pos
- buf
- 2;
730 /* A packet to be handled after seq response */
731 struct ft_remote_item
{
734 u8 nonce
[FT_RRB_NONCE_LEN
];
735 struct os_reltime nonce_ts
;
737 u8 src_addr
[ETH_ALEN
];
742 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
744 const u8
*enc
, size_t enc_len
,
745 const u8
*auth
, size_t auth_len
,
750 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
752 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
753 dl_list_del(&item
->list
);
754 bin_clear_free(item
->enc
, item
->enc_len
);
760 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
761 struct ft_remote_seq
*rkh_seq
, int cb
)
763 struct ft_remote_item
*item
, *n
;
765 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
766 struct ft_remote_item
, list
) {
768 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
769 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
770 wpa_ft_rrb_seq_free(item
);
775 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
777 struct ft_remote_item
*item
= timeout_ctx
;
779 wpa_ft_rrb_seq_free(item
);
784 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
785 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
786 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
787 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
788 const u8
*enc
, size_t enc_len
,
789 const u8
*auth
, size_t auth_len
,
790 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
792 const u8
*enc
, size_t enc_len
,
793 const u8
*auth
, size_t auth_len
,
796 struct ft_remote_item
*item
= NULL
;
799 struct tlv_list seq_req_auth
[] = {
800 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
801 .data
= NULL
/* to be filled: item->nonce */ },
802 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
804 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
806 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
809 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
810 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
814 item
= os_zalloc(sizeof(*item
));
818 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
821 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
822 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
826 if (os_get_reltime(&item
->nonce_ts
) < 0)
829 if (enc
&& enc_len
> 0) {
830 item
->enc
= os_memdup(enc
, enc_len
);
831 item
->enc_len
= enc_len
;
836 if (auth
&& auth_len
> 0) {
837 item
->auth
= os_memdup(auth
, auth_len
);
838 item
->auth_len
= auth_len
;
843 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
846 seq_req_auth
[0].data
= item
->nonce
;
848 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
849 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
850 &packet
, &packet_len
) < 0) {
851 item
= NULL
; /* some other seq resp might still accept this */
855 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
857 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
864 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
867 bin_clear_free(item
->enc
, item
->enc_len
);
875 #define FT_RRB_SEQ_OK 0
876 #define FT_RRB_SEQ_DROP 1
877 #define FT_RRB_SEQ_DEFER 2
880 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
881 const u8
*enc
, size_t enc_len
,
882 const u8
*auth
, size_t auth_len
,
883 const char *msgtype
, int no_defer
)
887 const struct ft_rrb_seq
*msg_both
;
888 u32 msg_seq
, msg_off
, rkh_off
;
889 struct os_reltime now
;
892 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
893 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
894 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
896 if (rkh_seq
->rx
.num_last
== 0) {
897 /* first packet from remote */
901 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
902 /* remote might have rebooted */
906 if (os_get_reltime(&now
) == 0) {
907 u32 msg_ts_now_remote
, msg_ts_off
;
908 struct os_reltime now_remote
;
910 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
911 msg_ts_now_remote
= now_remote
.sec
;
912 msg_ts_off
= le_to_host32(msg_both
->ts
) -
913 (msg_ts_now_remote
- ftRRBseqTimeout
);
914 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
918 msg_seq
= le_to_host32(msg_both
->seq
);
919 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
920 msg_off
= msg_seq
- rkh_off
;
921 if (msg_off
> 0xC0000000)
922 goto out
; /* too old message, drop it */
924 if (msg_off
<= 0x40000000) {
925 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
926 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
927 goto out
; /* duplicate message, drop it */
930 return FT_RRB_SEQ_OK
;
937 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
938 MACSTR
, msgtype
, MAC2STR(src_addr
));
940 return FT_RRB_SEQ_DEFER
;
942 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
943 msgtype
, MAC2STR(src_addr
));
945 return FT_RRB_SEQ_DROP
;
950 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
951 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
952 const u8
*auth
, size_t auth_len
,
957 const struct ft_rrb_seq
*msg_both
;
958 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
962 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
963 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
965 msg_seq
= le_to_host32(msg_both
->seq
);
967 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
968 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
969 rkh_seq
->rx
.num_last
++;
973 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
974 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
975 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
976 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
977 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
980 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
981 rkh_seq
->rx
.offsetidx
= minidx
;
985 /* RRB_GET_AUTH should never fail here as
986 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
987 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
991 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
992 struct ft_rrb_seq
*f_seq
)
994 struct os_reltime now
;
996 if (os_get_reltime(&now
) < 0)
999 if (!rkh_seq
->tx
.dom
) {
1000 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1001 sizeof(rkh_seq
->tx
.seq
))) {
1002 wpa_printf(MSG_ERROR
,
1003 "FT: Failed to get random data for sequence number initialization");
1004 rkh_seq
->tx
.seq
= now
.usec
;
1006 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1007 sizeof(rkh_seq
->tx
.dom
))) {
1008 wpa_printf(MSG_ERROR
,
1009 "FT: Failed to get random data for sequence number initialization");
1010 rkh_seq
->tx
.dom
= now
.usec
;
1012 rkh_seq
->tx
.dom
|= 1;
1015 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1016 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1017 f_seq
->ts
= host_to_le32(now
.sec
);
1025 struct wpa_ft_pmk_r0_sa
{
1026 struct dl_list list
;
1028 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1030 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1031 struct vlan_description
*vlan
;
1032 os_time_t expiration
; /* 0 for no expiration */
1033 /* TODO: identity, radius_class, EAP type */
1037 struct wpa_ft_pmk_r1_sa
{
1038 struct dl_list list
;
1040 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1042 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1043 struct vlan_description
*vlan
;
1044 /* TODO: expiration, identity, radius_class, EAP type */
1047 struct wpa_ft_pmk_cache
{
1048 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1049 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1053 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1054 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1057 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1062 dl_list_del(&r0
->list
);
1063 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1065 os_memset(r0
->pmk_r0
, 0, PMK_LEN
);
1071 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1073 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1074 struct os_reltime now
;
1077 os_get_reltime(&now
);
1082 expires_in
= r0
->expiration
- now
.sec
;
1083 if (expires_in
> 0) {
1084 wpa_printf(MSG_ERROR
,
1085 "FT: %s() called for non-expired entry %p, delete in %ds",
1086 __func__
, r0
, expires_in
);
1087 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1088 eloop_register_timeout(expires_in
+ 1, 0,
1089 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1093 wpa_ft_free_pmk_r0(r0
);
1097 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1102 dl_list_del(&r1
->list
);
1103 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1105 os_memset(r1
->pmk_r1
, 0, PMK_LEN
);
1111 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1113 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1115 wpa_ft_free_pmk_r1(r1
);
1119 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1121 struct wpa_ft_pmk_cache
*cache
;
1123 cache
= os_zalloc(sizeof(*cache
));
1125 dl_list_init(&cache
->pmk_r0
);
1126 dl_list_init(&cache
->pmk_r1
);
1133 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1135 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1136 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1138 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1139 struct wpa_ft_pmk_r0_sa
, list
)
1140 wpa_ft_free_pmk_r0(r0
);
1142 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1143 struct wpa_ft_pmk_r1_sa
, list
)
1144 wpa_ft_free_pmk_r1(r1
);
1150 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1151 const u8
*spa
, const u8
*pmk_r0
,
1152 const u8
*pmk_r0_name
, int pairwise
,
1153 const struct vlan_description
*vlan
,
1156 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1157 struct wpa_ft_pmk_r0_sa
*r0
;
1158 struct os_reltime now
;
1160 /* TODO: add limit on number of entries in cache */
1161 os_get_reltime(&now
);
1163 r0
= os_zalloc(sizeof(*r0
));
1167 os_memcpy(r0
->pmk_r0
, pmk_r0
, PMK_LEN
);
1168 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1169 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1170 r0
->pairwise
= pairwise
;
1172 r0
->expiration
= now
.sec
+ expires_in
;
1173 if (vlan
&& vlan
->notempty
) {
1174 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1176 bin_clear_free(r0
, sizeof(*r0
));
1182 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1184 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1191 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1192 const u8
*spa
, const u8
*pmk_r0_name
,
1193 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1195 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1196 struct wpa_ft_pmk_r0_sa
*r0
;
1197 struct os_reltime now
;
1199 os_get_reltime(&now
);
1200 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1201 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1202 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1203 WPA_PMK_NAME_LEN
) == 0) {
1214 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1215 const u8
*spa
, const u8
*pmk_r1
,
1216 const u8
*pmk_r1_name
, int pairwise
,
1217 const struct vlan_description
*vlan
,
1220 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1221 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1222 struct wpa_ft_pmk_r1_sa
*r1
;
1224 /* TODO: limit on number of entries in cache */
1226 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1227 expires_in
= max_expires_in
;
1229 r1
= os_zalloc(sizeof(*r1
));
1233 os_memcpy(r1
->pmk_r1
, pmk_r1
, PMK_LEN
);
1234 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1235 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1236 r1
->pairwise
= pairwise
;
1237 if (vlan
&& vlan
->notempty
) {
1238 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1240 bin_clear_free(r1
, sizeof(*r1
));
1246 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1249 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1256 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1257 const u8
*spa
, const u8
*pmk_r1_name
,
1258 u8
*pmk_r1
, int *pairwise
,
1259 struct vlan_description
*vlan
)
1261 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1262 struct wpa_ft_pmk_r1_sa
*r1
;
1264 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1265 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1266 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1267 WPA_PMK_NAME_LEN
) == 0) {
1268 os_memcpy(pmk_r1
, r1
->pmk_r1
, PMK_LEN
);
1270 *pairwise
= r1
->pairwise
;
1271 if (vlan
&& r1
->vlan
)
1273 if (vlan
&& !r1
->vlan
)
1274 os_memset(vlan
, 0, sizeof(*vlan
));
1283 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1288 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1290 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1294 dl_list_init(&r0kh
->seq
->rx
.queue
);
1300 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1301 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1302 struct ft_remote_r0kh
**r0kh_out
,
1303 struct ft_remote_r0kh
**r0kh_wildcard
)
1305 struct ft_remote_r0kh
*r0kh
;
1307 *r0kh_wildcard
= NULL
;
1310 if (wpa_auth
->conf
.r0kh_list
)
1311 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1314 for (; r0kh
; r0kh
= r0kh
->next
) {
1315 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1316 *r0kh_wildcard
= r0kh
;
1317 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1318 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1322 if (!*r0kh_out
&& !*r0kh_wildcard
)
1323 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1325 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1330 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1335 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1337 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1341 dl_list_init(&r1kh
->seq
->rx
.queue
);
1347 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1348 const u8
*f_r1kh_id
,
1349 struct ft_remote_r1kh
**r1kh_out
,
1350 struct ft_remote_r1kh
**r1kh_wildcard
)
1352 struct ft_remote_r1kh
*r1kh
;
1354 *r1kh_wildcard
= NULL
;
1357 if (wpa_auth
->conf
.r1kh_list
)
1358 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1361 for (; r1kh
; r1kh
= r1kh
->next
) {
1362 if (is_zero_ether_addr(r1kh
->addr
) &&
1363 is_zero_ether_addr(r1kh
->id
))
1364 *r1kh_wildcard
= r1kh
;
1366 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1370 if (!*r1kh_out
&& !*r1kh_wildcard
)
1371 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1373 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1378 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1379 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1381 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1382 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1383 f_r0kh_id_len
) != 0)
1390 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1391 const u8
*f_r1kh_id
)
1393 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1394 FT_R1KH_ID_LEN
) != 0)
1401 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1403 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1404 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1406 if (!wpa_auth
->conf
.r0kh_list
)
1409 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1410 if (r0kh
== timeout_ctx
)
1417 prev
->next
= r0kh
->next
;
1419 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1421 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1427 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1428 struct ft_remote_r0kh
*r0kh
, int timeout
)
1431 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1436 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1437 struct ft_remote_r0kh
*r0kh
, int timeout
)
1439 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1442 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1447 static struct ft_remote_r0kh
*
1448 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1449 struct ft_remote_r0kh
*r0kh_wildcard
,
1450 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1453 struct ft_remote_r0kh
*r0kh
;
1455 if (!wpa_auth
->conf
.r0kh_list
)
1458 r0kh
= os_zalloc(sizeof(*r0kh
));
1463 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1465 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1466 id_len
= FT_R0KH_ID_MAX_LEN
;
1467 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1468 r0kh
->id_len
= id_len
;
1470 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1472 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1473 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1476 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1479 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1486 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1488 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1489 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1491 if (!wpa_auth
->conf
.r1kh_list
)
1494 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1495 if (r1kh
== timeout_ctx
)
1502 prev
->next
= r1kh
->next
;
1504 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1506 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1512 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1513 struct ft_remote_r1kh
*r1kh
, int timeout
)
1516 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1521 static struct ft_remote_r1kh
*
1522 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1523 struct ft_remote_r1kh
*r1kh_wildcard
,
1524 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1526 struct ft_remote_r1kh
*r1kh
;
1528 if (!wpa_auth
->conf
.r1kh_list
)
1531 r1kh
= os_zalloc(sizeof(*r1kh
));
1535 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1536 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1537 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1538 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1539 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1542 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1545 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1552 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1554 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1558 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1560 struct ft_remote_r0kh
*r0kh
;
1561 struct ft_remote_r1kh
*r1kh
;
1563 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1565 if (wpa_auth
->conf
.r0kh_list
)
1566 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1569 for (; r0kh
; r0kh
= r0kh
->next
) {
1572 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1577 if (wpa_auth
->conf
.r1kh_list
)
1578 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1581 for (; r1kh
; r1kh
= r1kh
->next
) {
1584 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1591 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1593 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1594 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1596 if (wpa_auth
->conf
.r0kh_list
)
1597 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1601 r0kh_next
= r0kh
->next
;
1602 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1605 r0kh_prev
->next
= r0kh_next
;
1607 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1615 if (wpa_auth
->conf
.r1kh_list
)
1616 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1620 r1kh_next
= r1kh
->next
;
1621 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1624 r1kh_prev
->next
= r1kh_next
;
1626 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1636 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1638 wpa_ft_deinit_seq(wpa_auth
);
1639 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1643 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1644 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1646 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1648 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1651 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1652 &r0kh
, &r0kh_wildcard
);
1654 if (!r0kh_wildcard
) {
1655 /* r0kh removed after neg_timeout and might need re-adding */
1659 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1660 f_r0kh_id
, f_r0kh_id_len
);
1663 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1664 wpa_auth
->conf
.rkh_neg_timeout
);
1665 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1667 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1669 wpa_auth
->conf
.rkh_neg_timeout
);
1673 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1675 struct wpa_state_machine
*sm
= eloop_ctx
;
1677 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1679 if (sm
->ft_pending_pull_left_retries
<= 0)
1680 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1682 /* cancel multiple timeouts */
1683 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1688 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1689 const u8
*ies
, size_t ies_len
,
1690 const u8
*pmk_r0_name
)
1692 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1694 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1695 size_t packet_len
, key_len
;
1696 struct ft_rrb_seq f_seq
;
1697 int tsecs
, tusecs
, first
;
1698 struct wpabuf
*ft_pending_req_ies
;
1700 struct tlv_list req_enc
[] = {
1701 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1702 .data
= pmk_r0_name
},
1703 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1705 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1707 struct tlv_list req_auth
[] = {
1708 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1709 .data
= sm
->ft_pending_pull_nonce
},
1710 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1711 .data
= (u8
*) &f_seq
},
1712 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1713 .data
= sm
->r0kh_id
},
1714 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1715 .data
= f_r1kh_id
},
1716 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1719 if (sm
->ft_pending_pull_left_retries
<= 0)
1721 first
= sm
->ft_pending_pull_left_retries
==
1722 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1723 sm
->ft_pending_pull_left_retries
--;
1725 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1726 &r0kh
, &r0kh_wildcard
);
1728 /* Keep r0kh sufficiently long in the list for seq num check */
1729 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1730 1 + ftRRBseqTimeout
;
1732 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1733 } else if (r0kh_wildcard
) {
1734 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1735 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1736 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1737 r0kh_wildcard
->addr
,
1738 sm
->r0kh_id
, sm
->r0kh_id_len
,
1742 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1743 sm
->r0kh_id
, sm
->r0kh_id_len
);
1746 if (is_zero_ether_addr(r0kh
->addr
)) {
1747 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1748 sm
->r0kh_id
, sm
->r0kh_id_len
);
1751 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1752 wpa_printf(MSG_DEBUG
,
1753 "FT: R0KH-ID points to self - no matching key available");
1758 key_len
= sizeof(r0kh
->key
);
1760 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
1761 "address " MACSTR
, MAC2STR(r0kh
->addr
));
1763 if (r0kh
->seq
->rx
.num_last
== 0) {
1764 /* A sequence request will be sent out anyway when pull
1765 * response is received. Send it out now to avoid one RTT. */
1766 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
1767 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
1768 key_len
, NULL
, 0, NULL
, 0, NULL
);
1772 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
1773 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
1778 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
1779 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
1783 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
1784 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1785 &packet
, &packet_len
) < 0)
1788 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
1789 wpabuf_free(sm
->ft_pending_req_ies
);
1790 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
1791 if (!sm
->ft_pending_req_ies
) {
1796 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
1797 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
1798 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
1800 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1801 packet
, packet_len
);
1809 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
1810 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
1812 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
1813 struct vlan_description vlan
;
1815 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
1816 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
1821 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_name
,
1822 sm
->pairwise
, &vlan
, expires_in
);
1826 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, const u8
*pmk
,
1827 struct wpa_ptk
*ptk
)
1829 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
1831 u8 ptk_name
[WPA_PMK_NAME_LEN
];
1832 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
1833 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
1834 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
1835 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
1836 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
1837 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
1838 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
1839 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
1840 struct vlan_description vlan
;
1842 if (sm
->xxkey_len
== 0) {
1843 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
1848 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
1849 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
1854 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
1855 r0kh
, r0kh_len
, sm
->addr
,
1856 pmk_r0
, pmk_r0_name
) < 0)
1858 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, PMK_LEN
);
1859 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
1860 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
1861 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_name
,
1862 sm
->pairwise
, &vlan
, expires_in
);
1864 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
1865 pmk_r1
, sm
->pmk_r1_name
) < 0)
1867 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
1868 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
1870 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
1871 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
,
1872 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
1875 return wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
1876 sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
1877 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
1881 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
1882 const u8
*addr
, int idx
, u8
*seq
)
1884 if (wpa_auth
->cb
->get_seqnum
== NULL
)
1886 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
1890 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
1893 struct wpa_group
*gsm
= sm
->group
;
1894 size_t subelem_len
, pad_len
;
1899 key_len
= gsm
->GTK_len
;
1900 if (key_len
> sizeof(keybuf
))
1904 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
1907 pad_len
= key_len
% 8;
1909 pad_len
= 8 - pad_len
;
1910 if (key_len
+ pad_len
< 16)
1912 if (pad_len
&& key_len
< sizeof(keybuf
)) {
1913 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
1914 os_memset(keybuf
+ key_len
, 0, pad_len
);
1915 keybuf
[key_len
] = 0xdd;
1919 key
= gsm
->GTK
[gsm
->GN
- 1];
1922 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
1925 subelem_len
= 13 + key_len
+ 8;
1926 subelem
= os_zalloc(subelem_len
);
1927 if (subelem
== NULL
)
1930 subelem
[0] = FTIE_SUBELEM_GTK
;
1931 subelem
[1] = 11 + key_len
+ 8;
1932 /* Key ID in B0-B1 of Key Info */
1933 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
1934 subelem
[4] = gsm
->GTK_len
;
1935 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
1936 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, key_len
/ 8, key
,
1947 #ifdef CONFIG_IEEE80211W
1948 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
1951 struct wpa_group
*gsm
= sm
->group
;
1954 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
1956 subelem_len
= 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN
+ 8;
1957 subelem
= os_zalloc(subelem_len
);
1958 if (subelem
== NULL
)
1962 *pos
++ = FTIE_SUBELEM_IGTK
;
1963 *pos
++ = subelem_len
- 2;
1964 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
1966 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
1968 *pos
++ = WPA_IGTK_LEN
;
1969 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, WPA_IGTK_LEN
/ 8,
1970 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
1978 #endif /* CONFIG_IEEE80211W */
1981 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
1982 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
1983 const u8
*ies
, size_t ies_len
)
1985 struct ieee802_11_elems parse
;
1986 struct rsn_rdie
*rdie
;
1988 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
1990 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
1993 if (end
- pos
< (int) sizeof(*rdie
)) {
1994 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
1998 *pos
++ = WLAN_EID_RIC_DATA
;
1999 *pos
++ = sizeof(*rdie
);
2000 rdie
= (struct rsn_rdie
*) pos
;
2002 rdie
->descr_count
= 0;
2003 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2004 pos
+= sizeof(*rdie
);
2006 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2008 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2010 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2014 if (parse
.wmm_tspec
) {
2015 struct wmm_tspec_element
*tspec
;
2017 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2018 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2019 "(%d)", (int) parse
.wmm_tspec_len
);
2021 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2024 if (end
- pos
< (int) sizeof(*tspec
)) {
2025 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2028 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2031 tspec
= (struct wmm_tspec_element
*) pos
;
2032 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2036 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2039 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2040 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2041 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2043 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2044 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2046 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2048 /* TSPEC accepted; include updated TSPEC in response */
2049 rdie
->descr_count
= 1;
2050 pos
+= sizeof(struct wmm_tspec_element
);
2054 #endif /* NEED_AP_MLME */
2056 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2059 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2060 sizeof(struct wmm_tspec_element
));
2063 rdie
->status_code
= host_to_le16(res
);
2065 /* TSPEC accepted; include updated TSPEC in
2067 rdie
->descr_count
= 1;
2068 pos
+= sizeof(struct wmm_tspec_element
);
2074 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2075 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2080 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2081 const u8
*ric
, size_t ric_len
)
2083 const u8
*rpos
, *start
;
2084 const struct rsn_rdie
*rdie
;
2086 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2089 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2090 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2091 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2093 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2094 rpos
+= 2 + rpos
[1];
2097 while (rpos
+ 2 <= ric
+ ric_len
&&
2098 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2099 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2101 rpos
+= 2 + rpos
[1];
2103 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2105 start
, rpos
- start
);
2112 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2113 size_t max_len
, int auth_alg
,
2114 const u8
*req_ies
, size_t req_ies_len
)
2116 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2117 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2119 struct wpa_auth_config
*conf
;
2120 struct rsn_ftie
*_ftie
;
2121 struct wpa_ft_ies parse
;
2123 u8
*anonce
, *snonce
;
2130 conf
= &sm
->wpa_auth
->conf
;
2132 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2135 end
= pos
+ max_len
;
2137 if (auth_alg
== WLAN_AUTH_FT
) {
2139 * RSN (only present if this is a Reassociation Response and
2140 * part of a fast BSS transition)
2142 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2150 /* Mobility Domain Information */
2151 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2158 /* Fast BSS Transition Information */
2159 if (auth_alg
== WLAN_AUTH_FT
) {
2160 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2161 r0kh_id
= sm
->r0kh_id
;
2162 r0kh_id_len
= sm
->r0kh_id_len
;
2163 anonce
= sm
->ANonce
;
2164 snonce
= sm
->SNonce
;
2165 #ifdef CONFIG_IEEE80211W
2166 if (sm
->mgmt_frame_prot
) {
2170 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2175 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2182 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2183 subelem_len
+= igtk_len
;
2186 #endif /* CONFIG_IEEE80211W */
2188 r0kh_id
= conf
->r0_key_holder
;
2189 r0kh_id_len
= conf
->r0_key_holder_len
;
2193 res
= wpa_write_ftie(conf
, r0kh_id
, r0kh_id_len
, anonce
, snonce
, pos
,
2194 end
- pos
, subelem
, subelem_len
);
2202 _ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2203 if (auth_alg
== WLAN_AUTH_FT
)
2204 _ftie
->mic_control
[1] = 3; /* Information element count */
2207 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
) == 0 && parse
.ric
) {
2208 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2210 if (auth_alg
== WLAN_AUTH_FT
)
2211 _ftie
->mic_control
[1] +=
2212 ieee802_11_ie_count(ric_start
,
2215 if (ric_start
== pos
)
2218 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2220 kck_len
= sm
->PTK
.kck2_len
;
2223 kck_len
= sm
->PTK
.kck_len
;
2225 if (auth_alg
== WLAN_AUTH_FT
&&
2226 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2227 mdie
, mdie_len
, ftie
, ftie_len
,
2229 ric_start
, ric_start
? pos
- ric_start
: 0,
2231 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2233 os_free(sm
->assoc_resp_ftie
);
2234 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2235 if (sm
->assoc_resp_ftie
)
2236 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2242 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2244 enum wpa_alg alg
, const u8
*addr
, int idx
,
2245 u8
*key
, size_t key_len
)
2247 if (wpa_auth
->cb
->set_key
== NULL
)
2249 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2254 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
2259 /* MLME-SETKEYS.request(PTK) */
2260 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2261 klen
= wpa_cipher_key_len(sm
->pairwise
);
2262 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2263 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2264 "PTK configuration", sm
->pairwise
);
2268 if (sm
->tk_already_set
) {
2269 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2270 * PN in the driver */
2271 wpa_printf(MSG_DEBUG
,
2272 "FT: Do not re-install same PTK to the driver");
2276 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2277 * most likely without this.. At the moment, STA entry is added only
2278 * after association has been completed. This function will be called
2279 * again after association to get the PTK configured, but that could be
2280 * optimized by adding the STA entry earlier.
2282 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
2286 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2287 sm
->pairwise_set
= TRUE
;
2288 sm
->tk_already_set
= TRUE
;
2292 /* Derive PMK-R1 from PSK, check all available PSK */
2293 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2294 const u8
*req_pmk_r1_name
,
2295 u8
*out_pmk_r1
, int *out_pairwise
,
2296 struct vlan_description
*out_vlan
)
2298 const u8
*pmk
= NULL
;
2299 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2300 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2301 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2302 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2303 const u8
*r0kh
= sm
->r0kh_id
;
2304 size_t r0kh_len
= sm
->r0kh_id_len
;
2305 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2306 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2307 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2310 pairwise
= sm
->pairwise
;
2313 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2318 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2320 pmk_r0
, pmk_r0_name
) < 0 ||
2321 wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
2322 pmk_r1
, pmk_r1_name
) < 0 ||
2323 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2324 WPA_PMK_NAME_LEN
) != 0)
2327 /* We found a PSK that matches the requested pmk_r1_name */
2328 wpa_printf(MSG_DEBUG
,
2329 "FT: Found PSK to generate PMK-R1 locally");
2330 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2332 *out_pairwise
= pairwise
;
2334 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2335 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2336 MACSTR
, MAC2STR(sm
->addr
));
2343 wpa_printf(MSG_DEBUG
,
2344 "FT: Did not find PSK to generate PMK-R1 locally");
2349 /* Detect the configuration the station asked for.
2350 * Required to detect FT-PSK and pairwise cipher.
2352 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2353 struct wpa_ft_ies
*parse
)
2355 int key_mgmt
, ciphers
;
2357 if (sm
->wpa_key_mgmt
)
2360 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2362 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2363 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2366 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2367 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2368 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2369 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2371 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2372 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2373 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2374 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2375 #endif /* CONFIG_FILS */
2376 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2378 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2380 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2383 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2389 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2390 struct wpa_state_machine
*sm
,
2391 const u8
*r0kh_id
, size_t r0kh_id_len
,
2392 const u8
*req_pmk_r0_name
,
2393 const u8
*req_pmk_r1_name
,
2394 u8
*out_pmk_r1
, int *out_pairwise
,
2395 struct vlan_description
*vlan
)
2397 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2398 const struct wpa_ft_pmk_r0_sa
*r0
;
2399 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2402 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2403 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2405 return -1; /* not our R0KH-ID */
2407 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2408 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2410 return -1; /* no matching PMKR0Name in local cache */
2412 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2414 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_name
, conf
->r1_key_holder
,
2415 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2417 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, PMK_LEN
);
2418 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2420 if (r0
->expiration
) {
2421 struct os_reltime now
;
2423 os_get_reltime(&now
);
2424 expires_in
= r0
->expiration
- now
.sec
;
2427 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, pmk_r1_name
,
2428 sm
->pairwise
, r0
->vlan
, expires_in
);
2430 *out_pairwise
= sm
->pairwise
;
2435 os_memset(vlan
, 0, sizeof(*vlan
));
2441 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2442 const u8
*ies
, size_t ies_len
,
2443 u8
**resp_ies
, size_t *resp_ies_len
)
2445 struct rsn_mdie
*mdie
;
2446 struct rsn_ftie
*ftie
;
2447 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2448 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2449 struct wpa_auth_config
*conf
;
2450 struct wpa_ft_ies parse
;
2455 struct vlan_description vlan
;
2460 sm
->pmk_r1_name_valid
= 0;
2461 conf
= &sm
->wpa_auth
->conf
;
2463 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2466 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2467 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2468 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2471 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2472 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2473 os_memcmp(mdie
->mobility_domain
,
2474 sm
->wpa_auth
->conf
.mobility_domain
,
2475 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2476 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2477 return WLAN_STATUS_INVALID_MDIE
;
2480 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2481 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2482 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2483 return WLAN_STATUS_INVALID_FTIE
;
2486 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2488 if (parse
.r0kh_id
== NULL
) {
2489 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2490 return WLAN_STATUS_INVALID_FTIE
;
2493 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2494 parse
.r0kh_id
, parse
.r0kh_id_len
);
2495 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2496 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2498 if (parse
.rsn_pmkid
== NULL
) {
2499 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2500 return WLAN_STATUS_INVALID_PMKID
;
2503 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2504 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2506 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2507 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2508 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2509 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2511 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2512 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2513 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2515 if (conf
->ft_psk_generate_local
&&
2516 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2517 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
2519 return WLAN_STATUS_INVALID_PMKID
;
2520 wpa_printf(MSG_DEBUG
,
2521 "FT: Generated PMK-R1 for FT-PSK locally");
2522 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2523 pmk_r1
, &pairwise
, &vlan
) < 0) {
2524 wpa_printf(MSG_DEBUG
,
2525 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2526 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2527 parse
.r0kh_id
, parse
.r0kh_id_len
,
2529 pmk_r1_name
, pmk_r1
, &pairwise
,
2531 wpa_printf(MSG_DEBUG
,
2532 "FT: Generated PMK-R1 based on local PMK-R0");
2533 goto pmk_r1_derived
;
2536 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2537 wpa_printf(MSG_DEBUG
,
2538 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2539 return WLAN_STATUS_INVALID_PMKID
;
2542 return -1; /* Status pending */
2544 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2548 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, PMK_LEN
);
2549 sm
->pmk_r1_name_valid
= 1;
2550 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2552 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2553 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2555 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2558 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2559 sm
->SNonce
, WPA_NONCE_LEN
);
2560 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2561 sm
->ANonce
, WPA_NONCE_LEN
);
2563 if (wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
2564 sm
->wpa_auth
->addr
, pmk_r1_name
,
2565 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
2567 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2569 sm
->pairwise
= pairwise
;
2570 sm
->PTK_valid
= TRUE
;
2571 sm
->tk_already_set
= FALSE
;
2572 wpa_ft_install_ptk(sm
);
2574 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2575 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
2576 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2579 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
2580 2 + FT_R1KH_ID_LEN
+ 200;
2581 *resp_ies
= os_zalloc(buflen
);
2582 if (*resp_ies
== NULL
)
2586 end
= *resp_ies
+ buflen
;
2588 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
2593 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
2598 ret
= wpa_write_ftie(conf
, parse
.r0kh_id
, parse
.r0kh_id_len
,
2599 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
2604 *resp_ies_len
= pos
- *resp_ies
;
2606 return WLAN_STATUS_SUCCESS
;
2610 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2614 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
2615 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
2616 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
2617 u16 auth_transaction
, u16 status
,
2618 const u8
*ies
, size_t ies_len
),
2623 size_t resp_ies_len
;
2627 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
2628 "WPA SM not available");
2632 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
2633 " BSSID=" MACSTR
" transaction=%d",
2634 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
2635 sm
->ft_pending_cb
= cb
;
2636 sm
->ft_pending_cb_ctx
= ctx
;
2637 sm
->ft_pending_auth_transaction
= auth_transaction
;
2638 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2639 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
2642 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
2647 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
2648 " auth_transaction=%d status=%d",
2649 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
2650 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2651 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
2652 resp_ies
, resp_ies_len
);
2657 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
2660 struct wpa_ft_ies parse
;
2661 struct rsn_mdie
*mdie
;
2662 struct rsn_ftie
*ftie
;
2663 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
2664 size_t mic_len
= 16;
2670 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2672 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
2674 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2675 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2676 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2679 if (parse
.rsn
== NULL
) {
2680 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
2681 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2684 if (parse
.rsn_pmkid
== NULL
) {
2685 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2686 return WLAN_STATUS_INVALID_PMKID
;
2689 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
2691 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
2692 "with the PMKR1Name derived from auth request");
2693 return WLAN_STATUS_INVALID_PMKID
;
2696 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2697 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2698 os_memcmp(mdie
->mobility_domain
,
2699 sm
->wpa_auth
->conf
.mobility_domain
,
2700 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2701 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2702 return WLAN_STATUS_INVALID_MDIE
;
2705 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2706 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2707 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2708 return WLAN_STATUS_INVALID_FTIE
;
2711 if (os_memcmp(ftie
->snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
2712 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
2713 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2714 ftie
->snonce
, WPA_NONCE_LEN
);
2715 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
2716 sm
->SNonce
, WPA_NONCE_LEN
);
2717 return WLAN_STATUS_INVALID_FTIE
;
2720 if (os_memcmp(ftie
->anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
2721 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
2722 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
2723 ftie
->anonce
, WPA_NONCE_LEN
);
2724 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
2725 sm
->ANonce
, WPA_NONCE_LEN
);
2726 return WLAN_STATUS_INVALID_FTIE
;
2730 if (parse
.r0kh_id
== NULL
) {
2731 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
2732 return WLAN_STATUS_INVALID_FTIE
;
2735 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
2736 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
2738 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
2739 "the current R0KH-ID");
2740 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
2741 parse
.r0kh_id
, parse
.r0kh_id_len
);
2742 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
2743 sm
->r0kh_id
, sm
->r0kh_id_len
);
2744 return WLAN_STATUS_INVALID_FTIE
;
2747 if (parse
.r1kh_id
== NULL
) {
2748 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
2749 return WLAN_STATUS_INVALID_FTIE
;
2752 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
2753 FT_R1KH_ID_LEN
) != 0) {
2754 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
2756 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
2757 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
2758 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
2759 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
2760 return WLAN_STATUS_INVALID_FTIE
;
2763 if (parse
.rsn_pmkid
== NULL
||
2764 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
2766 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
2767 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
2768 return WLAN_STATUS_INVALID_PMKID
;
2773 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
2774 if (ftie
->mic_control
[1] != count
) {
2775 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
2776 "Control: received %u expected %u",
2777 ftie
->mic_control
[1], count
);
2778 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2781 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2783 kck_len
= sm
->PTK
.kck2_len
;
2786 kck_len
= sm
->PTK
.kck_len
;
2788 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
2789 parse
.mdie
- 2, parse
.mdie_len
+ 2,
2790 parse
.ftie
- 2, parse
.ftie_len
+ 2,
2791 parse
.rsn
- 2, parse
.rsn_len
+ 2,
2792 parse
.ric
, parse
.ric_len
,
2794 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2795 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2798 if (os_memcmp_const(mic
, ftie
->mic
, mic_len
) != 0) {
2799 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
2800 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
2801 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
2802 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
2803 ftie
->mic
, mic_len
);
2804 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
2805 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
2806 parse
.mdie
- 2, parse
.mdie_len
+ 2);
2807 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
2808 parse
.ftie
- 2, parse
.ftie_len
+ 2);
2809 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
2810 parse
.rsn
- 2, parse
.rsn_len
+ 2);
2811 return WLAN_STATUS_INVALID_FTIE
;
2814 return WLAN_STATUS_SUCCESS
;
2818 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
2820 const u8
*sta_addr
, *target_ap
;
2824 struct ft_rrb_frame
*frame
;
2830 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
2831 * FT Request action frame body[variable]
2835 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
2836 "(len=%lu)", (unsigned long) len
);
2841 sta_addr
= data
+ 2;
2842 target_ap
= data
+ 8;
2846 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
2847 " Target AP=" MACSTR
" Action=%d)",
2848 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
2850 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
2851 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
2852 "STA=" MACSTR
" STA-Address=" MACSTR
,
2853 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
2858 * Do some sanity checking on the target AP address (not own and not
2859 * broadcast. This could be extended to filter based on a list of known
2860 * APs in the MD (if such a list were configured).
2862 if ((target_ap
[0] & 0x01) ||
2863 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
2864 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
2869 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
2871 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
2872 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
2876 /* RRB - Forward action frame to the target AP */
2877 frame
= os_malloc(sizeof(*frame
) + len
);
2880 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
2881 frame
->packet_type
= FT_PACKET_REQUEST
;
2882 frame
->action_length
= host_to_le16(len
);
2883 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
2884 os_memcpy(frame
+ 1, data
, len
);
2886 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
2887 sizeof(*frame
) + len
);
2894 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
2895 u16 auth_transaction
, u16 resp
,
2896 const u8
*ies
, size_t ies_len
)
2898 struct wpa_state_machine
*sm
= ctx
;
2899 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
2901 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
2902 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
2906 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
2907 const u8
*current_ap
, const u8
*sta_addr
,
2908 const u8
*body
, size_t len
)
2910 struct wpa_state_machine
*sm
;
2913 size_t resp_ies_len
;
2916 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
2918 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
2923 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
2925 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
2926 sm
->ft_pending_cb_ctx
= sm
;
2927 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
2928 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2929 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
2932 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
2937 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
2938 resp_ies
, resp_ies_len
);
2944 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
2945 const u8
*current_ap
, const u8
*sta_addr
,
2946 u16 status
, const u8
*resp_ies
,
2947 size_t resp_ies_len
)
2949 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2951 struct ft_rrb_frame
*frame
;
2954 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
2955 " CurrentAP=" MACSTR
" status=%d",
2956 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
2957 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2959 /* RRB - Forward action frame response to the Current AP */
2962 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
2963 * Status_Code[2] FT Request action frame body[variable]
2965 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
2967 frame
= os_malloc(sizeof(*frame
) + rlen
);
2970 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
2971 frame
->packet_type
= FT_PACKET_RESPONSE
;
2972 frame
->action_length
= host_to_le16(rlen
);
2973 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
2974 pos
= (u8
*) (frame
+ 1);
2975 *pos
++ = WLAN_ACTION_FT
;
2976 *pos
++ = 2; /* Action: Response */
2977 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
2979 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
2981 WPA_PUT_LE16(pos
, status
);
2984 os_memcpy(pos
, resp_ies
, resp_ies_len
);
2986 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
2987 sizeof(*frame
) + rlen
);
2994 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
2995 const struct tlv_list
*tlvs
,
2996 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
2997 const u8
*r1kh_id
, const u8
*s1kh_id
,
2998 const struct tlv_list
*tlv_auth
,
2999 const u8
*src_addr
, u8 type
,
3000 u8
**packet
, size_t *packet_len
)
3003 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3004 u8 f_pairwise
[sizeof(le16
)];
3005 u8 f_expires_in
[sizeof(le16
)];
3007 struct os_reltime now
;
3009 struct tlv_list sess_tlv
[] = {
3010 { .type
= FT_RRB_PMK_R1
, .len
= sizeof(pmk_r1
),
3012 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3013 .data
= pmk_r1_name
},
3014 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3015 .data
= f_pairwise
},
3016 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3017 .data
= f_expires_in
},
3018 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3022 return wpa_ft_rrb_build(key
, key_len
, tlvs
, NULL
, tlv_auth
,
3023 NULL
, src_addr
, type
,
3024 packet
, packet_len
);
3026 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_name
, r1kh_id
,
3027 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3029 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
3030 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
3031 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3033 os_get_reltime(&now
);
3034 if (pmk_r0
->expiration
> now
.sec
)
3035 expires_in
= pmk_r0
->expiration
- now
.sec
;
3036 else if (pmk_r0
->expiration
)
3040 WPA_PUT_LE16(f_expires_in
, expires_in
);
3042 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3043 pmk_r0
->vlan
, src_addr
, type
,
3044 packet
, packet_len
);
3046 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
3052 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3054 const u8
*enc
, size_t enc_len
,
3055 const u8
*auth
, size_t auth_len
,
3058 const char *msgtype
= "pull request";
3059 u8
*plain
= NULL
, *packet
= NULL
;
3060 size_t plain_len
= 0, packet_len
= 0;
3061 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3065 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3066 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3067 size_t f_pmk_r0_name_len
;
3068 const struct wpa_ft_pmk_r0_sa
*r0
;
3070 struct tlv_list resp
[2];
3071 struct tlv_list resp_auth
[5];
3072 struct ft_rrb_seq f_seq
;
3074 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3076 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3077 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3079 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3080 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3084 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3085 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3087 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3090 key_len
= sizeof(r1kh
->key
);
3091 } else if (r1kh_wildcard
) {
3092 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3093 key
= r1kh_wildcard
->key
;
3094 key_len
= sizeof(r1kh_wildcard
->key
);
3099 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3100 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3102 seq_ret
= FT_RRB_SEQ_DROP
;
3104 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3105 auth
, auth_len
, msgtype
, no_defer
);
3106 if (!no_defer
&& r1kh_wildcard
&&
3107 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3108 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3109 seq_ret
= FT_RRB_SEQ_DEFER
;
3112 if (seq_ret
== FT_RRB_SEQ_DROP
)
3115 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3116 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3117 &plain
, &plain_len
) < 0)
3121 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3123 wpa_auth
->conf
.rkh_pos_timeout
);
3127 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3128 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3129 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3130 enc
, enc_len
, auth
, auth_len
,
3131 &wpa_ft_rrb_rx_pull
);
3135 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3137 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3138 wpa_auth
->conf
.rkh_pos_timeout
);
3140 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3141 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3144 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3145 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3147 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3148 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3152 resp
[0].type
= FT_RRB_S1KH_ID
;
3153 resp
[0].len
= f_s1kh_id_len
;
3154 resp
[0].data
= f_s1kh_id
;
3155 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3157 resp
[1].data
= NULL
;
3159 resp_auth
[0].type
= FT_RRB_NONCE
;
3160 resp_auth
[0].len
= f_nonce_len
;
3161 resp_auth
[0].data
= f_nonce
;
3162 resp_auth
[1].type
= FT_RRB_SEQ
;
3163 resp_auth
[1].len
= sizeof(f_seq
);
3164 resp_auth
[1].data
= (u8
*) &f_seq
;
3165 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3166 resp_auth
[2].len
= f_r0kh_id_len
;
3167 resp_auth
[2].data
= f_r0kh_id
;
3168 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3169 resp_auth
[3].len
= f_r1kh_id_len
;
3170 resp_auth
[3].data
= f_r1kh_id
;
3171 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3172 resp_auth
[4].len
= 0;
3173 resp_auth
[4].data
= NULL
;
3175 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0)
3176 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3178 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
, f_s1kh_id
,
3179 resp_auth
, wpa_auth
->addr
,
3180 FT_PACKET_R0KH_R1KH_RESP
,
3181 &packet
, &packet_len
);
3184 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3185 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3196 /* @returns 0 on success
3198 * -2 if FR_RRB_PAIRWISE is missing
3200 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3201 const u8
*src_addr
, u8 type
,
3202 const u8
*enc
, size_t enc_len
,
3203 const u8
*auth
, size_t auth_len
,
3204 const char *msgtype
, u8
*s1kh_id_out
,
3205 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3207 const u8
*enc
, size_t enc_len
,
3208 const u8
*auth
, size_t auth_len
,
3212 size_t plain_len
= 0;
3213 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3217 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3218 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3219 const u8
*f_expires_in
;
3220 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3221 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3222 size_t f_expires_in_len
;
3226 struct vlan_description vlan
;
3228 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3229 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3231 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3232 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3234 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3235 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3239 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3243 key_len
= sizeof(r0kh
->key
);
3244 } else if (r0kh_wildcard
) {
3245 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3246 key
= r0kh_wildcard
->key
;
3247 key_len
= sizeof(r0kh_wildcard
->key
);
3252 seq_ret
= FT_RRB_SEQ_DROP
;
3254 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3255 auth
, auth_len
, msgtype
,
3258 if (cb
&& r0kh_wildcard
&&
3259 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3260 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3261 seq_ret
= FT_RRB_SEQ_DEFER
;
3264 if (seq_ret
== FT_RRB_SEQ_DROP
)
3267 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3268 src_addr
, type
, &plain
, &plain_len
) < 0)
3272 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3273 f_r0kh_id
, f_r0kh_id_len
,
3274 wpa_auth
->conf
.rkh_pos_timeout
);
3278 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3279 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3280 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3281 enc
, enc_len
, auth
, auth_len
, cb
);
3285 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3287 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3288 wpa_auth
->conf
.rkh_pos_timeout
);
3290 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3291 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3294 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3297 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3298 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3301 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3302 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3303 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
3305 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, PMK_LEN
);
3306 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, PMK_LEN
);
3308 pairwise
= WPA_GET_LE16(f_pairwise
);
3310 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
3313 expires_in
= WPA_GET_LE16(f_expires_in
);
3317 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
3320 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
3321 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
3322 wpa_ft_rrb_dump(plain
, plain_len
);
3326 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
3327 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
3329 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, f_pmk_r1_name
,
3330 pairwise
, &vlan
, expires_in
) < 0)
3336 os_memset(plain
, 0, plain_len
);
3345 static void ft_finish_pull(struct wpa_state_machine
*sm
)
3349 size_t resp_ies_len
;
3352 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
3355 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
3356 wpabuf_len(sm
->ft_pending_req_ies
),
3357 &resp_ies
, &resp_ies_len
);
3359 /* this loop is broken by ft_pending_pull_left_retries */
3360 wpa_printf(MSG_DEBUG
,
3361 "FT: Callback postponed until response is available");
3364 wpabuf_free(sm
->ft_pending_req_ies
);
3365 sm
->ft_pending_req_ies
= NULL
;
3367 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
3368 " - status %u", MAC2STR(sm
->addr
), status
);
3370 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
3371 sm
->ft_pending_auth_transaction
+ 1, status
,
3372 resp_ies
, resp_ies_len
);
3377 struct ft_get_sta_ctx
{
3380 struct wpa_state_machine
*sm
;
3384 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3386 struct ft_get_sta_ctx
*info
= ctx
;
3388 if ((info
->s1kh_id
&&
3389 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3390 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3391 FT_RRB_NONCE_LEN
) != 0 ||
3392 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3401 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3403 const u8
*enc
, size_t enc_len
,
3404 const u8
*auth
, size_t auth_len
,
3407 const char *msgtype
= "pull response";
3409 struct ft_get_sta_ctx ctx
;
3410 u8 s1kh_id
[ETH_ALEN
];
3414 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3416 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3417 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3419 os_memset(&ctx
, 0, sizeof(ctx
));
3420 ctx
.nonce
= f_nonce
;
3421 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3422 /* nonce not found */
3423 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3427 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3428 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3429 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3439 ctx
.s1kh_id
= s1kh_id
;
3440 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3441 wpa_printf(MSG_DEBUG
,
3442 "FT: Response to a pending pull request for " MACSTR
,
3443 MAC2STR(ctx
.sm
->addr
));
3444 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3446 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3447 ft_finish_pull(ctx
.sm
);
3455 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
3457 const u8
*enc
, size_t enc_len
,
3458 const u8
*auth
, size_t auth_len
, int no_defer
)
3460 const char *msgtype
= "push";
3462 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
3464 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3465 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
3466 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
3473 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
3474 const u8
*src_addr
, int type
,
3475 const u8
*enc
, size_t enc_len
,
3476 const u8
*auth
, size_t auth_len
,
3477 struct ft_remote_seq
**rkh_seq
,
3478 u8
**key
, size_t *key_len
,
3479 struct ft_remote_r0kh
**r0kh_out
,
3480 struct ft_remote_r1kh
**r1kh_out
,
3481 struct ft_remote_r0kh
**r0kh_wildcard_out
,
3482 struct ft_remote_r1kh
**r1kh_wildcard_out
)
3484 struct ft_remote_r0kh
*r0kh
= NULL
;
3485 struct ft_remote_r1kh
*r1kh
= NULL
;
3486 const u8
*f_r0kh_id
, *f_r1kh_id
;
3487 size_t f_r0kh_id_len
, f_r1kh_id_len
;
3488 int to_r0kh
, to_r1kh
;
3490 size_t plain_len
= 0;
3491 struct ft_remote_r0kh
*r0kh_wildcard
;
3492 struct ft_remote_r1kh
*r1kh_wildcard
;
3494 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3495 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3497 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
3498 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
3500 if (to_r0kh
&& to_r1kh
) {
3501 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
3505 if (!to_r0kh
&& !to_r1kh
) {
3506 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
3511 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
3512 &r0kh
, &r0kh_wildcard
);
3513 if (!r0kh_wildcard
&&
3514 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3515 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
3516 f_r0kh_id
, f_r0kh_id_len
);
3521 *key_len
= sizeof(r0kh
->key
);
3523 *key
= r0kh_wildcard
->key
;
3524 *key_len
= sizeof(r0kh_wildcard
->key
);
3529 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
3531 if (!r1kh_wildcard
&&
3532 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3533 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
3534 f_r1kh_id
, FT_R1KH_ID_LEN
);
3539 *key_len
= sizeof(r1kh
->key
);
3541 *key
= r1kh_wildcard
->key
;
3542 *key_len
= sizeof(r1kh_wildcard
->key
);
3546 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
3547 src_addr
, type
, &plain
, &plain_len
) < 0)
3554 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
3555 src_addr
, f_r0kh_id
,
3561 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
3562 *rkh_seq
= r0kh
->seq
;
3565 if (r0kh_wildcard_out
)
3566 *r0kh_wildcard_out
= r0kh_wildcard
;
3571 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
3572 src_addr
, f_r1kh_id
,
3577 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
3578 *rkh_seq
= r1kh
->seq
;
3581 if (r1kh_wildcard_out
)
3582 *r1kh_wildcard_out
= r1kh_wildcard
;
3591 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
3593 const u8
*enc
, size_t enc_len
,
3594 const u8
*auth
, size_t auth_len
,
3598 struct ft_rrb_seq f_seq
;
3599 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
3600 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
3601 struct ft_remote_seq
*rkh_seq
= NULL
;
3602 u8
*packet
= NULL
, *key
= NULL
;
3603 size_t packet_len
= 0, key_len
= 0;
3604 struct tlv_list seq_resp_auth
[5];
3606 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
3608 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
3609 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3610 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
3613 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
3614 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
3616 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3617 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3619 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
3620 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3624 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
3625 seq_resp_auth
[0].len
= f_nonce_len
;
3626 seq_resp_auth
[0].data
= f_nonce
;
3627 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
3628 seq_resp_auth
[1].len
= sizeof(f_seq
);
3629 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
3630 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3631 seq_resp_auth
[2].len
= f_r0kh_id_len
;
3632 seq_resp_auth
[2].data
= f_r0kh_id
;
3633 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3634 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
3635 seq_resp_auth
[3].data
= f_r1kh_id
;
3636 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3637 seq_resp_auth
[4].len
= 0;
3638 seq_resp_auth
[4].data
= NULL
;
3640 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
3641 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3642 &packet
, &packet_len
) < 0)
3645 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3646 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
3656 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
3658 const u8
*enc
, size_t enc_len
,
3659 const u8
*auth
, size_t auth_len
,
3664 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
3665 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
3666 const u8
*f_nonce
, *f_seq
;
3667 size_t f_nonce_len
, f_seq_len
;
3668 struct ft_remote_seq
*rkh_seq
= NULL
;
3669 struct ft_remote_item
*item
;
3670 struct os_reltime now
, now_remote
;
3672 const struct ft_rrb_seq
*msg_both
;
3673 u32 msg_dom
, msg_seq
;
3675 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
3677 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3678 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3679 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
3680 &r1kh_wildcard
) < 0)
3683 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
3684 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
3688 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
3690 if (os_memcmp_const(f_nonce
, item
->nonce
,
3691 FT_RRB_NONCE_LEN
) != 0 ||
3692 os_get_reltime(&now
) < 0 ||
3693 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
3700 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
3705 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3706 wpa_auth
->conf
.rkh_pos_timeout
);
3708 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
3712 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3713 wpa_auth
->conf
.rkh_pos_timeout
);
3715 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
3718 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
3719 auth_len
, "seq response", 1);
3720 if (seq_ret
== FT_RRB_SEQ_OK
) {
3721 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
3722 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
3723 auth_len
, "seq response");
3725 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
3727 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
3729 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
3731 msg_dom
= le_to_host32(msg_both
->dom
);
3732 msg_seq
= le_to_host32(msg_both
->seq
);
3733 now_remote
.sec
= le_to_host32(msg_both
->ts
);
3734 now_remote
.usec
= 0;
3736 rkh_seq
->rx
.num_last
= 2;
3737 rkh_seq
->rx
.dom
= msg_dom
;
3738 rkh_seq
->rx
.offsetidx
= 0;
3739 /* Accept some older, possibly cached packets as well */
3740 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
3741 dl_list_len(&rkh_seq
->rx
.queue
);
3742 rkh_seq
->rx
.last
[1] = msg_seq
;
3744 /* local time - offset = remote time
3745 * <=> local time - remote time = offset */
3746 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
3749 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
3757 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
3758 const u8
*data
, size_t data_len
)
3760 struct ft_rrb_frame
*frame
;
3762 const u8
*pos
, *end
, *start
;
3764 const u8
*sta_addr
, *target_ap_addr
;
3766 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
3769 if (data_len
< sizeof(*frame
)) {
3770 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
3771 (unsigned long) data_len
);
3776 frame
= (struct ft_rrb_frame
*) pos
;
3777 pos
+= sizeof(*frame
);
3779 alen
= le_to_host16(frame
->action_length
);
3780 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
3781 "action_length=%d ap_address=" MACSTR
,
3782 frame
->frame_type
, frame
->packet_type
, alen
,
3783 MAC2STR(frame
->ap_address
));
3785 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
3786 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
3787 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
3788 "unrecognized type %d", frame
->frame_type
);
3792 if (alen
> data_len
- sizeof(*frame
)) {
3793 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
3798 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
3800 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
3801 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
3802 "room for Action Frame body); alen=%lu",
3803 (unsigned long) alen
);
3809 if (*pos
!= WLAN_ACTION_FT
) {
3810 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
3819 target_ap_addr
= pos
;
3821 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
3822 MACSTR
" target_ap_addr=" MACSTR
,
3823 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
3825 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
3826 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
3829 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
3830 "RRB Request", action
);
3834 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
3835 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
3836 "RRB Request does not match with own "
3841 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
3842 sta_addr
, pos
, end
- pos
) < 0)
3844 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
3847 if (end
- pos
< 2) {
3848 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
3849 "code in RRB Response");
3852 status_code
= WPA_GET_LE16(pos
);
3855 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
3856 "(status_code=%d)", status_code
);
3858 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
3861 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
3862 "packet_type %d", frame
->packet_type
);
3867 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
3875 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
3876 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
3879 const u8
*auth
, *enc
;
3883 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
3884 MACSTR
, MAC2STR(src_addr
));
3885 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
3887 if (is_multicast_ether_addr(src_addr
)) {
3888 wpa_printf(MSG_DEBUG
,
3889 "FT: RRB-OUI received frame from multicast address "
3890 MACSTR
, MAC2STR(src_addr
));
3894 if (is_multicast_ether_addr(dst_addr
)) {
3895 wpa_printf(MSG_DEBUG
,
3896 "FT: RRB-OUI received frame from remote AP " MACSTR
3897 " to multicast address " MACSTR
,
3898 MAC2STR(src_addr
), MAC2STR(dst_addr
));
3902 if (data_len
< sizeof(u16
)) {
3903 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
3907 alen
= WPA_GET_LE16(data
);
3908 if (data_len
< sizeof(u16
) + alen
) {
3909 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
3913 auth
= data
+ sizeof(u16
);
3914 enc
= data
+ sizeof(u16
) + alen
;
3915 elen
= data_len
- sizeof(u16
) - alen
;
3917 switch (oui_suffix
) {
3918 case FT_PACKET_R0KH_R1KH_PULL
:
3919 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3922 case FT_PACKET_R0KH_R1KH_RESP
:
3923 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3926 case FT_PACKET_R0KH_R1KH_PUSH
:
3927 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3930 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
3931 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3934 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
3935 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
3942 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
3943 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3944 struct ft_remote_r1kh
*r1kh
,
3949 struct ft_rrb_seq f_seq
;
3950 struct tlv_list push
[] = {
3951 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
3953 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
3954 .data
= pmk_r0
->pmk_r0_name
},
3955 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3957 struct tlv_list push_auth
[] = {
3958 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
3959 .data
= (u8
*) &f_seq
},
3960 { .type
= FT_RRB_R0KH_ID
,
3961 .len
= wpa_auth
->conf
.r0_key_holder_len
,
3962 .data
= wpa_auth
->conf
.r0_key_holder
},
3963 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
3965 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3968 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3969 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3973 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
3974 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
3975 FT_PACKET_R0KH_R1KH_PUSH
,
3976 &packet
, &packet_len
) < 0)
3979 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3980 packet
, packet_len
);
3987 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
3989 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
3990 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
3991 struct ft_remote_r1kh
*r1kh
;
3993 if (!wpa_auth
->conf
.pmk_r1_push
)
3995 if (!wpa_auth
->conf
.r1kh_list
)
3998 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
3999 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4006 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4008 r0
->pmk_r1_pushed
= 1;
4010 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4011 "for STA " MACSTR
, MAC2STR(addr
));
4013 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4014 if (is_zero_ether_addr(r1kh
->addr
) ||
4015 is_zero_ether_addr(r1kh
->id
))
4017 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4019 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4023 #endif /* CONFIG_IEEE80211R_AP */