2 * hostapd - IEEE 802.11r - Fast BSS Transition
3 * Copyright (c) 2004-2018, 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 "common/ocv.h"
17 #include "drivers/driver.h"
18 #include "crypto/aes.h"
19 #include "crypto/aes_siv.h"
20 #include "crypto/aes_wrap.h"
21 #include "crypto/sha384.h"
22 #include "crypto/random.h"
23 #include "ap_config.h"
24 #include "ieee802_11.h"
27 #include "wpa_auth_i.h"
30 #ifdef CONFIG_IEEE80211R_AP
32 const unsigned int ftRRBseqTimeout
= 10;
33 const unsigned int ftRRBmaxQueueLen
= 100;
36 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
37 const u8
*current_ap
, const u8
*sta_addr
,
38 u16 status
, const u8
*resp_ies
,
40 static void ft_finish_pull(struct wpa_state_machine
*sm
);
41 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
42 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
52 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
53 * @key: AES-SIV key for AEAD
54 * @key_len: Length of key in octets
55 * @enc: Pointer to encrypted TLVs
56 * @enc_len: Length of encrypted TLVs in octets
57 * @auth: Pointer to authenticated TLVs
58 * @auth_len: Length of authenticated TLVs in octets
59 * @src_addr: MAC address of the frame sender
60 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
61 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
62 * needs to be freed by the caller if not NULL;
63 * will only be returned on success
64 * @plain_len: Pointer to return the length of the allocated plaintext buffer
66 * Returns: 0 on success, -1 on error
68 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
69 const u8
*enc
, const size_t enc_len
,
70 const u8
*auth
, const size_t auth_len
,
71 const u8
*src_addr
, u8 type
,
72 u8
**plain
, size_t *plain_size
)
74 const u8
*ad
[3] = { src_addr
, auth
, &type
};
75 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
77 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
79 if (!key
) { /* skip decryption */
80 *plain
= os_memdup(enc
, enc_len
);
81 if (enc_len
> 0 && !*plain
)
84 *plain_size
= enc_len
;
92 if (enc_len
< AES_BLOCK_SIZE
)
95 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
99 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
103 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
104 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
105 *plain
, *plain_size
);
112 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
118 /* get first tlv record in packet matching type
119 * @data (decrypted) packet
120 * @return 0 on success else -1
122 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
123 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
125 const struct ft_rrb_tlv
*f
;
131 type16
= host_to_le16(type
);
133 while (left
>= sizeof(*f
)) {
134 f
= (const struct ft_rrb_tlv
*) plain
;
138 len
= le_to_host16(f
->len
);
141 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
145 if (f
->type
== type16
) {
159 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
161 const struct ft_rrb_tlv
*f
;
167 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
168 while (left
>= sizeof(*f
)) {
169 f
= (const struct ft_rrb_tlv
*) plain
;
173 len
= le_to_host16(f
->len
);
175 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
176 le_to_host16(f
->type
), len
);
179 wpa_printf(MSG_DEBUG
,
180 "FT: RRB message truncated: left %zu bytes, need %zu",
185 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
192 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
194 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
198 static int cmp_int(const void *a
, const void *b
)
208 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
209 struct vlan_description
*vlan
)
211 struct ft_rrb_tlv
*f
;
220 os_memset(vlan
, 0, sizeof(*vlan
));
222 while (left
>= sizeof(*f
)) {
223 f
= (struct ft_rrb_tlv
*) plain
;
228 len
= le_to_host16(f
->len
);
229 type
= le_to_host16(f
->type
);
232 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
236 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
239 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
240 wpa_printf(MSG_DEBUG
,
241 "FT: RRB VLAN_UNTAGGED invalid length");
245 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
246 wpa_printf(MSG_DEBUG
,
247 "FT: RRB VLAN_TAGGED invalid length");
251 while (len
>= sizeof(le16
)) {
252 vlan_id
= WPA_GET_LE16(plain
);
253 plain
+= sizeof(le16
);
254 left
-= sizeof(le16
);
257 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
258 wpa_printf(MSG_DEBUG
,
259 "FT: RRB VLAN ID invalid %d",
264 if (type
== FT_RRB_VLAN_UNTAGGED
)
265 vlan
->untagged
= vlan_id
;
267 if (type
== FT_RRB_VLAN_TAGGED
&&
268 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
269 vlan
->tagged
[taggedidx
] = vlan_id
;
271 } else if (type
== FT_RRB_VLAN_TAGGED
) {
272 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
282 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
284 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
290 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
298 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
299 tlv_len
+= sizeof(struct ft_rrb_tlv
);
300 tlv_len
+= tlvs
[i
].len
;
307 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
312 struct ft_rrb_tlv
*hdr
;
320 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
321 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
323 tlv_len
+= sizeof(*hdr
);
324 hdr
= (struct ft_rrb_tlv
*) pos
;
325 hdr
->type
= host_to_le16(tlvs
[i
].type
);
326 hdr
->len
= host_to_le16(tlvs
[i
].len
);
327 pos
= start
+ tlv_len
;
329 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
331 if (tlvs
[i
].len
== 0)
333 tlv_len
+= tlvs
[i
].len
;
334 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
335 pos
= start
+ tlv_len
;
342 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
347 if (!vlan
|| !vlan
->notempty
)
350 if (vlan
->untagged
) {
351 tlv_len
+= sizeof(struct ft_rrb_tlv
);
352 tlv_len
+= sizeof(le16
);
355 tlv_len
+= sizeof(struct ft_rrb_tlv
);
356 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
357 tlv_len
+= sizeof(le16
);
363 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
364 u8
*start
, u8
*endpos
)
368 struct ft_rrb_tlv
*hdr
;
371 if (!vlan
|| !vlan
->notempty
)
375 if (vlan
->untagged
) {
376 tlv_len
+= sizeof(*hdr
);
377 if (start
+ tlv_len
> endpos
)
379 hdr
= (struct ft_rrb_tlv
*) pos
;
380 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
381 hdr
->len
= host_to_le16(sizeof(le16
));
382 pos
= start
+ tlv_len
;
384 tlv_len
+= sizeof(le16
);
385 if (start
+ tlv_len
> endpos
)
387 WPA_PUT_LE16(pos
, vlan
->untagged
);
388 pos
= start
+ tlv_len
;
391 if (!vlan
->tagged
[0])
394 tlv_len
+= sizeof(*hdr
);
395 if (start
+ tlv_len
> endpos
)
397 hdr
= (struct ft_rrb_tlv
*) pos
;
398 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
399 len
= 0; /* len is computed below */
400 pos
= start
+ tlv_len
;
402 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
403 tlv_len
+= sizeof(le16
);
404 if (start
+ tlv_len
> endpos
)
407 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
408 pos
= start
+ tlv_len
;
411 hdr
->len
= host_to_le16(len
);
417 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
418 const struct tlv_list
*tlvs2
,
419 const struct vlan_description
*vlan
,
420 u8
**plain
, size_t *plain_len
)
425 tlv_len
= wpa_ft_tlv_len(tlvs1
);
426 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
427 tlv_len
+= wpa_ft_vlan_len(vlan
);
429 *plain_len
= tlv_len
;
430 *plain
= os_zalloc(tlv_len
);
432 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
437 endpos
= *plain
+ tlv_len
;
438 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
439 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
440 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
444 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
458 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
459 const u8
*plain
, const size_t plain_len
,
460 const u8
*auth
, const size_t auth_len
,
461 const u8
*src_addr
, u8 type
, u8
*enc
)
463 const u8
*ad
[3] = { src_addr
, auth
, &type
};
464 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
466 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
468 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
471 /* encryption not needed, return plaintext as packet */
472 os_memcpy(enc
, plain
, plain_len
);
473 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
474 3, ad
, ad_len
, enc
) < 0) {
475 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
484 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
485 * @key: AES-SIV key for AEAD
486 * @key_len: Length of key in octets
487 * @tlvs_enc0: First set of to-be-encrypted TLVs
488 * @tlvs_enc1: Second set of to-be-encrypted TLVs
489 * @tlvs_auth: Set of to-be-authenticated TLVs
490 * @src_addr: MAC address of the frame sender
491 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
492 * @packet Pointer to return the pointer to the allocated packet buffer;
493 * needs to be freed by the caller if not null;
494 * will only be returned on success
495 * @packet_len: Pointer to return the length of the allocated buffer in octets
496 * Returns: 0 on success, -1 on error
498 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
499 const struct tlv_list
*tlvs_enc0
,
500 const struct tlv_list
*tlvs_enc1
,
501 const struct tlv_list
*tlvs_auth
,
502 const struct vlan_description
*vlan
,
503 const u8
*src_addr
, u8 type
,
504 u8
**packet
, size_t *packet_len
)
506 u8
*plain
= NULL
, *auth
= NULL
, *pos
;
507 size_t plain_len
= 0, auth_len
= 0;
511 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
514 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
517 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
519 *packet_len
+= AES_BLOCK_SIZE
;
520 *packet
= os_zalloc(*packet_len
);
525 WPA_PUT_LE16(pos
, auth_len
);
527 os_memcpy(pos
, auth
, auth_len
);
529 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
530 auth_len
, src_addr
, type
, pos
) < 0)
536 bin_clear_free(plain
, plain_len
);
540 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
550 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
551 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
552 &f_##field##_len, &f_##field) < 0 || \
553 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
554 wpa_printf(MSG_INFO, "FT: Missing required " #field \
555 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
556 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
561 #define RRB_GET(type, field, txt, checklength) \
562 RRB_GET_SRC(plain, type, field, txt, checklength)
563 #define RRB_GET_AUTH(type, field, txt, checklength) \
564 RRB_GET_SRC(auth, type, field, txt, checklength)
566 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
567 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
568 &f_##field##_len, &f_##field) < 0 || \
569 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
570 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
571 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
572 f_##field##_len = 0; \
577 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
578 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
579 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
580 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
582 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
583 const u8
*data
, size_t data_len
)
585 if (wpa_auth
->cb
->send_ether
== NULL
)
587 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
588 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
593 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
594 const u8
*dst
, u8 oui_suffix
,
595 const u8
*data
, size_t data_len
)
597 if (!wpa_auth
->cb
->send_oui
)
599 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
,
600 oui_suffix
, MAC2STR(dst
));
601 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
606 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
607 const u8
*dst
, const u8
*data
, size_t data_len
)
609 if (wpa_auth
->cb
->send_ft_action
== NULL
)
611 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
616 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
617 const u8
*addr
, const u8
*p2p_dev_addr
,
620 if (wpa_auth
->cb
->get_psk
== NULL
)
622 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
627 static struct wpa_state_machine
*
628 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
630 if (wpa_auth
->cb
->add_sta
== NULL
)
632 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
636 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
637 const u8
*sta_addr
, struct vlan_description
*vlan
)
639 if (!wpa_auth
->cb
->set_vlan
)
641 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
645 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
646 const u8
*sta_addr
, struct vlan_description
*vlan
)
648 if (!wpa_auth
->cb
->get_vlan
)
650 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
655 wpa_ft_set_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
656 const u8
*identity
, size_t identity_len
)
658 if (!wpa_auth
->cb
->set_identity
)
660 return wpa_auth
->cb
->set_identity(wpa_auth
->cb_ctx
, sta_addr
, identity
,
666 wpa_ft_get_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
670 if (!wpa_auth
->cb
->get_identity
)
672 return wpa_auth
->cb
->get_identity(wpa_auth
->cb_ctx
, sta_addr
, buf
);
677 wpa_ft_set_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
678 const u8
*radius_cui
, size_t radius_cui_len
)
680 if (!wpa_auth
->cb
->set_radius_cui
)
682 return wpa_auth
->cb
->set_radius_cui(wpa_auth
->cb_ctx
, sta_addr
,
683 radius_cui
, radius_cui_len
);
688 wpa_ft_get_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
692 if (!wpa_auth
->cb
->get_radius_cui
)
694 return wpa_auth
->cb
->get_radius_cui(wpa_auth
->cb_ctx
, sta_addr
, buf
);
699 wpa_ft_set_session_timeout(struct wpa_authenticator
*wpa_auth
,
700 const u8
*sta_addr
, int session_timeout
)
702 if (!wpa_auth
->cb
->set_session_timeout
)
704 wpa_auth
->cb
->set_session_timeout(wpa_auth
->cb_ctx
, sta_addr
,
710 wpa_ft_get_session_timeout(struct wpa_authenticator
*wpa_auth
,
713 if (!wpa_auth
->cb
->get_session_timeout
)
715 return wpa_auth
->cb
->get_session_timeout(wpa_auth
->cb_ctx
, sta_addr
);
719 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
721 u8
*tspec_ie
, size_t tspec_ielen
)
723 if (wpa_auth
->cb
->add_tspec
== NULL
) {
724 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
727 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
733 static int wpa_channel_info(struct wpa_authenticator
*wpa_auth
,
734 struct wpa_channel_info
*ci
)
736 if (!wpa_auth
->cb
->channel_info
)
738 return wpa_auth
->cb
->channel_info(wpa_auth
->cb_ctx
, ci
);
740 #endif /* CONFIG_OCV */
743 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
747 if (len
< 2 + sizeof(struct rsn_mdie
))
750 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
751 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
752 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
753 pos
+= MOBILITY_DOMAIN_ID_LEN
;
755 if (conf
->ft_over_ds
)
756 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
763 int wpa_write_ftie(struct wpa_auth_config
*conf
, int use_sha384
,
764 const u8
*r0kh_id
, size_t r0kh_id_len
,
765 const u8
*anonce
, const u8
*snonce
,
766 u8
*buf
, size_t len
, const u8
*subelem
,
769 u8
*pos
= buf
, *ielen
;
770 size_t hdrlen
= use_sha384
? sizeof(struct rsn_ftie_sha384
) :
771 sizeof(struct rsn_ftie
);
773 if (len
< 2 + hdrlen
+ 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
777 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
781 struct rsn_ftie_sha384
*hdr
= (struct rsn_ftie_sha384
*) pos
;
783 os_memset(hdr
, 0, sizeof(*hdr
));
785 WPA_PUT_LE16(hdr
->mic_control
, 0);
787 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
789 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
791 struct rsn_ftie
*hdr
= (struct rsn_ftie
*) pos
;
793 os_memset(hdr
, 0, sizeof(*hdr
));
795 WPA_PUT_LE16(hdr
->mic_control
, 0);
797 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
799 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
802 /* Optional Parameters */
803 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
804 *pos
++ = FT_R1KH_ID_LEN
;
805 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
806 pos
+= FT_R1KH_ID_LEN
;
809 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
810 *pos
++ = r0kh_id_len
;
811 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
816 os_memcpy(pos
, subelem
, subelem_len
);
820 *ielen
= pos
- buf
- 2;
826 /* A packet to be handled after seq response */
827 struct ft_remote_item
{
830 u8 nonce
[FT_RRB_NONCE_LEN
];
831 struct os_reltime nonce_ts
;
833 u8 src_addr
[ETH_ALEN
];
838 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
840 const u8
*enc
, size_t enc_len
,
841 const u8
*auth
, size_t auth_len
,
846 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
848 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
849 dl_list_del(&item
->list
);
850 bin_clear_free(item
->enc
, item
->enc_len
);
856 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
857 struct ft_remote_seq
*rkh_seq
, int cb
)
859 struct ft_remote_item
*item
, *n
;
861 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
862 struct ft_remote_item
, list
) {
864 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
865 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
866 wpa_ft_rrb_seq_free(item
);
871 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
873 struct ft_remote_item
*item
= timeout_ctx
;
875 wpa_ft_rrb_seq_free(item
);
880 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
881 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
882 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
883 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
884 const u8
*enc
, size_t enc_len
,
885 const u8
*auth
, size_t auth_len
,
886 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
888 const u8
*enc
, size_t enc_len
,
889 const u8
*auth
, size_t auth_len
,
892 struct ft_remote_item
*item
= NULL
;
895 struct tlv_list seq_req_auth
[] = {
896 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
897 .data
= NULL
/* to be filled: item->nonce */ },
898 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
900 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
902 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
905 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
906 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
910 item
= os_zalloc(sizeof(*item
));
914 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
917 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
918 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
922 if (os_get_reltime(&item
->nonce_ts
) < 0)
925 if (enc
&& enc_len
> 0) {
926 item
->enc
= os_memdup(enc
, enc_len
);
927 item
->enc_len
= enc_len
;
932 if (auth
&& auth_len
> 0) {
933 item
->auth
= os_memdup(auth
, auth_len
);
934 item
->auth_len
= auth_len
;
939 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
942 seq_req_auth
[0].data
= item
->nonce
;
944 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
945 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
946 &packet
, &packet_len
) < 0) {
947 item
= NULL
; /* some other seq resp might still accept this */
951 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
953 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
960 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
963 bin_clear_free(item
->enc
, item
->enc_len
);
971 #define FT_RRB_SEQ_OK 0
972 #define FT_RRB_SEQ_DROP 1
973 #define FT_RRB_SEQ_DEFER 2
976 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
977 const u8
*enc
, size_t enc_len
,
978 const u8
*auth
, size_t auth_len
,
979 const char *msgtype
, int no_defer
)
983 const struct ft_rrb_seq
*msg_both
;
984 u32 msg_seq
, msg_off
, rkh_off
;
985 struct os_reltime now
;
988 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
989 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
990 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
992 if (rkh_seq
->rx
.num_last
== 0) {
993 /* first packet from remote */
997 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
998 /* remote might have rebooted */
1002 if (os_get_reltime(&now
) == 0) {
1003 u32 msg_ts_now_remote
, msg_ts_off
;
1004 struct os_reltime now_remote
;
1006 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
1007 msg_ts_now_remote
= now_remote
.sec
;
1008 msg_ts_off
= le_to_host32(msg_both
->ts
) -
1009 (msg_ts_now_remote
- ftRRBseqTimeout
);
1010 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
1014 msg_seq
= le_to_host32(msg_both
->seq
);
1015 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1016 msg_off
= msg_seq
- rkh_off
;
1017 if (msg_off
> 0xC0000000)
1018 goto out
; /* too old message, drop it */
1020 if (msg_off
<= 0x40000000) {
1021 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1022 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
1023 goto out
; /* duplicate message, drop it */
1026 return FT_RRB_SEQ_OK
;
1033 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
1034 MACSTR
, msgtype
, MAC2STR(src_addr
));
1036 return FT_RRB_SEQ_DEFER
;
1038 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
1039 msgtype
, MAC2STR(src_addr
));
1041 return FT_RRB_SEQ_DROP
;
1046 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
1047 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1048 const u8
*auth
, size_t auth_len
,
1049 const char *msgtype
)
1053 const struct ft_rrb_seq
*msg_both
;
1054 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
1058 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1059 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1061 msg_seq
= le_to_host32(msg_both
->seq
);
1063 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
1064 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
1065 rkh_seq
->rx
.num_last
++;
1069 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1070 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1071 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
1072 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
1073 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
1076 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
1077 rkh_seq
->rx
.offsetidx
= minidx
;
1081 /* RRB_GET_AUTH should never fail here as
1082 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1083 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
1087 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
1088 struct ft_rrb_seq
*f_seq
)
1090 struct os_reltime now
;
1092 if (os_get_reltime(&now
) < 0)
1095 if (!rkh_seq
->tx
.dom
) {
1096 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1097 sizeof(rkh_seq
->tx
.seq
))) {
1098 wpa_printf(MSG_ERROR
,
1099 "FT: Failed to get random data for sequence number initialization");
1100 rkh_seq
->tx
.seq
= now
.usec
;
1102 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1103 sizeof(rkh_seq
->tx
.dom
))) {
1104 wpa_printf(MSG_ERROR
,
1105 "FT: Failed to get random data for sequence number initialization");
1106 rkh_seq
->tx
.dom
= now
.usec
;
1108 rkh_seq
->tx
.dom
|= 1;
1111 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1112 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1113 f_seq
->ts
= host_to_le32(now
.sec
);
1121 struct wpa_ft_pmk_r0_sa
{
1122 struct dl_list list
;
1123 u8 pmk_r0
[PMK_LEN_MAX
];
1125 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1127 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1128 struct vlan_description
*vlan
;
1129 os_time_t expiration
; /* 0 for no expiration */
1131 size_t identity_len
;
1133 size_t radius_cui_len
;
1134 os_time_t session_timeout
; /* 0 for no expiration */
1135 /* TODO: radius_class, EAP type */
1139 struct wpa_ft_pmk_r1_sa
{
1140 struct dl_list list
;
1141 u8 pmk_r1
[PMK_LEN_MAX
];
1143 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1145 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1146 struct vlan_description
*vlan
;
1148 size_t identity_len
;
1150 size_t radius_cui_len
;
1151 os_time_t session_timeout
; /* 0 for no expiration */
1152 /* TODO: radius_class, EAP type */
1155 struct wpa_ft_pmk_cache
{
1156 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1157 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1161 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1162 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1165 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1170 dl_list_del(&r0
->list
);
1171 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1173 os_memset(r0
->pmk_r0
, 0, PMK_LEN_MAX
);
1175 os_free(r0
->identity
);
1176 os_free(r0
->radius_cui
);
1181 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1183 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1184 struct os_reltime now
;
1186 int session_timeout
;
1188 os_get_reltime(&now
);
1193 expires_in
= r0
->expiration
- now
.sec
;
1194 session_timeout
= r0
->session_timeout
- now
.sec
;
1195 /* conditions to remove from cache:
1196 * a) r0->expiration is set and hit
1198 * b) r0->session_timeout is set and hit
1200 if ((!r0
->expiration
|| expires_in
> 0) &&
1201 (!r0
->session_timeout
|| session_timeout
> 0)) {
1202 wpa_printf(MSG_ERROR
,
1203 "FT: %s() called for non-expired entry %p",
1205 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1206 if (r0
->expiration
&& expires_in
> 0)
1207 eloop_register_timeout(expires_in
+ 1, 0,
1208 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1209 if (r0
->session_timeout
&& session_timeout
> 0)
1210 eloop_register_timeout(session_timeout
+ 1, 0,
1211 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1215 wpa_ft_free_pmk_r0(r0
);
1219 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1224 dl_list_del(&r1
->list
);
1225 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1227 os_memset(r1
->pmk_r1
, 0, PMK_LEN_MAX
);
1229 os_free(r1
->identity
);
1230 os_free(r1
->radius_cui
);
1235 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1237 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1239 wpa_ft_free_pmk_r1(r1
);
1243 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1245 struct wpa_ft_pmk_cache
*cache
;
1247 cache
= os_zalloc(sizeof(*cache
));
1249 dl_list_init(&cache
->pmk_r0
);
1250 dl_list_init(&cache
->pmk_r1
);
1257 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1259 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1260 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1262 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1263 struct wpa_ft_pmk_r0_sa
, list
)
1264 wpa_ft_free_pmk_r0(r0
);
1266 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1267 struct wpa_ft_pmk_r1_sa
, list
)
1268 wpa_ft_free_pmk_r1(r1
);
1274 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1275 const u8
*spa
, const u8
*pmk_r0
,
1277 const u8
*pmk_r0_name
, int pairwise
,
1278 const struct vlan_description
*vlan
,
1279 int expires_in
, int session_timeout
,
1280 const u8
*identity
, size_t identity_len
,
1281 const u8
*radius_cui
, size_t radius_cui_len
)
1283 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1284 struct wpa_ft_pmk_r0_sa
*r0
;
1285 struct os_reltime now
;
1287 /* TODO: add limit on number of entries in cache */
1288 os_get_reltime(&now
);
1290 r0
= os_zalloc(sizeof(*r0
));
1294 os_memcpy(r0
->pmk_r0
, pmk_r0
, pmk_r0_len
);
1295 r0
->pmk_r0_len
= pmk_r0_len
;
1296 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1297 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1298 r0
->pairwise
= pairwise
;
1300 r0
->expiration
= now
.sec
+ expires_in
;
1301 if (vlan
&& vlan
->notempty
) {
1302 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1304 bin_clear_free(r0
, sizeof(*r0
));
1310 r0
->identity
= os_malloc(identity_len
);
1312 os_memcpy(r0
->identity
, identity
, identity_len
);
1313 r0
->identity_len
= identity_len
;
1317 r0
->radius_cui
= os_malloc(radius_cui_len
);
1318 if (r0
->radius_cui
) {
1319 os_memcpy(r0
->radius_cui
, radius_cui
, radius_cui_len
);
1320 r0
->radius_cui_len
= radius_cui_len
;
1323 if (session_timeout
> 0)
1324 r0
->session_timeout
= now
.sec
+ session_timeout
;
1326 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1328 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1330 if (session_timeout
> 0)
1331 eloop_register_timeout(session_timeout
+ 1, 0,
1332 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1338 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1339 const u8
*spa
, const u8
*pmk_r0_name
,
1340 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1342 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1343 struct wpa_ft_pmk_r0_sa
*r0
;
1344 struct os_reltime now
;
1346 os_get_reltime(&now
);
1347 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1348 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1349 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1350 WPA_PMK_NAME_LEN
) == 0) {
1361 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1362 const u8
*spa
, const u8
*pmk_r1
,
1364 const u8
*pmk_r1_name
, int pairwise
,
1365 const struct vlan_description
*vlan
,
1366 int expires_in
, int session_timeout
,
1367 const u8
*identity
, size_t identity_len
,
1368 const u8
*radius_cui
, size_t radius_cui_len
)
1370 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1371 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1372 struct wpa_ft_pmk_r1_sa
*r1
;
1373 struct os_reltime now
;
1375 /* TODO: limit on number of entries in cache */
1376 os_get_reltime(&now
);
1378 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1379 expires_in
= max_expires_in
;
1381 r1
= os_zalloc(sizeof(*r1
));
1385 os_memcpy(r1
->pmk_r1
, pmk_r1
, pmk_r1_len
);
1386 r1
->pmk_r1_len
= pmk_r1_len
;
1387 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1388 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1389 r1
->pairwise
= pairwise
;
1390 if (vlan
&& vlan
->notempty
) {
1391 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1393 bin_clear_free(r1
, sizeof(*r1
));
1399 r1
->identity
= os_malloc(identity_len
);
1401 os_memcpy(r1
->identity
, identity
, identity_len
);
1402 r1
->identity_len
= identity_len
;
1406 r1
->radius_cui
= os_malloc(radius_cui_len
);
1407 if (r1
->radius_cui
) {
1408 os_memcpy(r1
->radius_cui
, radius_cui
, radius_cui_len
);
1409 r1
->radius_cui_len
= radius_cui_len
;
1412 if (session_timeout
> 0)
1413 r1
->session_timeout
= now
.sec
+ session_timeout
;
1415 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1418 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1420 if (session_timeout
> 0)
1421 eloop_register_timeout(session_timeout
+ 1, 0,
1422 wpa_ft_expire_pmk_r1
, r1
, NULL
);
1428 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1429 const u8
*spa
, const u8
*pmk_r1_name
,
1430 u8
*pmk_r1
, size_t *pmk_r1_len
, int *pairwise
,
1431 struct vlan_description
*vlan
,
1432 const u8
**identity
, size_t *identity_len
,
1433 const u8
**radius_cui
, size_t *radius_cui_len
,
1434 int *session_timeout
)
1436 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1437 struct wpa_ft_pmk_r1_sa
*r1
;
1438 struct os_reltime now
;
1440 os_get_reltime(&now
);
1442 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1443 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1444 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1445 WPA_PMK_NAME_LEN
) == 0) {
1446 os_memcpy(pmk_r1
, r1
->pmk_r1
, r1
->pmk_r1_len
);
1447 *pmk_r1_len
= r1
->pmk_r1_len
;
1449 *pairwise
= r1
->pairwise
;
1450 if (vlan
&& r1
->vlan
)
1452 if (vlan
&& !r1
->vlan
)
1453 os_memset(vlan
, 0, sizeof(*vlan
));
1454 if (identity
&& identity_len
) {
1455 *identity
= r1
->identity
;
1456 *identity_len
= r1
->identity_len
;
1458 if (radius_cui
&& radius_cui_len
) {
1459 *radius_cui
= r1
->radius_cui
;
1460 *radius_cui_len
= r1
->radius_cui_len
;
1462 if (session_timeout
&& r1
->session_timeout
> now
.sec
)
1463 *session_timeout
= r1
->session_timeout
-
1465 else if (session_timeout
&& r1
->session_timeout
)
1466 *session_timeout
= 1;
1467 else if (session_timeout
)
1468 *session_timeout
= 0;
1477 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1482 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1484 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1488 dl_list_init(&r0kh
->seq
->rx
.queue
);
1494 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1495 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1496 struct ft_remote_r0kh
**r0kh_out
,
1497 struct ft_remote_r0kh
**r0kh_wildcard
)
1499 struct ft_remote_r0kh
*r0kh
;
1501 *r0kh_wildcard
= NULL
;
1504 if (wpa_auth
->conf
.r0kh_list
)
1505 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1508 for (; r0kh
; r0kh
= r0kh
->next
) {
1509 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1510 *r0kh_wildcard
= r0kh
;
1511 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1512 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1516 if (!*r0kh_out
&& !*r0kh_wildcard
)
1517 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1519 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1524 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1529 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1531 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1535 dl_list_init(&r1kh
->seq
->rx
.queue
);
1541 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1542 const u8
*f_r1kh_id
,
1543 struct ft_remote_r1kh
**r1kh_out
,
1544 struct ft_remote_r1kh
**r1kh_wildcard
)
1546 struct ft_remote_r1kh
*r1kh
;
1548 *r1kh_wildcard
= NULL
;
1551 if (wpa_auth
->conf
.r1kh_list
)
1552 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1555 for (; r1kh
; r1kh
= r1kh
->next
) {
1556 if (is_zero_ether_addr(r1kh
->addr
) &&
1557 is_zero_ether_addr(r1kh
->id
))
1558 *r1kh_wildcard
= r1kh
;
1560 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1564 if (!*r1kh_out
&& !*r1kh_wildcard
)
1565 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1567 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1572 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1573 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1575 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1576 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1577 f_r0kh_id_len
) != 0)
1584 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1585 const u8
*f_r1kh_id
)
1587 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1588 FT_R1KH_ID_LEN
) != 0)
1595 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1597 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1598 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1600 if (!wpa_auth
->conf
.r0kh_list
)
1603 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1604 if (r0kh
== timeout_ctx
)
1611 prev
->next
= r0kh
->next
;
1613 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1615 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1621 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1622 struct ft_remote_r0kh
*r0kh
, int timeout
)
1625 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1630 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1631 struct ft_remote_r0kh
*r0kh
, int timeout
)
1633 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1636 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1641 static struct ft_remote_r0kh
*
1642 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1643 struct ft_remote_r0kh
*r0kh_wildcard
,
1644 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1647 struct ft_remote_r0kh
*r0kh
;
1649 if (!wpa_auth
->conf
.r0kh_list
)
1652 r0kh
= os_zalloc(sizeof(*r0kh
));
1657 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1659 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1660 id_len
= FT_R0KH_ID_MAX_LEN
;
1661 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1662 r0kh
->id_len
= id_len
;
1664 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1666 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1667 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1670 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1673 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1680 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1682 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1683 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1685 if (!wpa_auth
->conf
.r1kh_list
)
1688 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1689 if (r1kh
== timeout_ctx
)
1696 prev
->next
= r1kh
->next
;
1698 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1700 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1706 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1707 struct ft_remote_r1kh
*r1kh
, int timeout
)
1710 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1715 static struct ft_remote_r1kh
*
1716 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1717 struct ft_remote_r1kh
*r1kh_wildcard
,
1718 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1720 struct ft_remote_r1kh
*r1kh
;
1722 if (!wpa_auth
->conf
.r1kh_list
)
1725 r1kh
= os_zalloc(sizeof(*r1kh
));
1729 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1730 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1731 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1732 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1733 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1736 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1739 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1746 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1748 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1752 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1754 struct ft_remote_r0kh
*r0kh
;
1755 struct ft_remote_r1kh
*r1kh
;
1757 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1759 if (wpa_auth
->conf
.r0kh_list
)
1760 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1763 for (; r0kh
; r0kh
= r0kh
->next
) {
1766 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1771 if (wpa_auth
->conf
.r1kh_list
)
1772 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1775 for (; r1kh
; r1kh
= r1kh
->next
) {
1778 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1785 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1787 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1788 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1790 if (wpa_auth
->conf
.r0kh_list
)
1791 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1795 r0kh_next
= r0kh
->next
;
1796 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1799 r0kh_prev
->next
= r0kh_next
;
1801 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1809 if (wpa_auth
->conf
.r1kh_list
)
1810 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1814 r1kh_next
= r1kh
->next
;
1815 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1818 r1kh_prev
->next
= r1kh_next
;
1820 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1830 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1832 wpa_ft_deinit_seq(wpa_auth
);
1833 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1837 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1838 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1840 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1842 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1845 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1846 &r0kh
, &r0kh_wildcard
);
1848 if (!r0kh_wildcard
) {
1849 /* r0kh removed after neg_timeout and might need re-adding */
1853 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1854 f_r0kh_id
, f_r0kh_id_len
);
1857 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1858 wpa_auth
->conf
.rkh_neg_timeout
);
1859 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1861 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1863 wpa_auth
->conf
.rkh_neg_timeout
);
1867 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1869 struct wpa_state_machine
*sm
= eloop_ctx
;
1871 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1873 if (sm
->ft_pending_pull_left_retries
<= 0)
1874 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1876 /* cancel multiple timeouts */
1877 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1882 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1883 const u8
*ies
, size_t ies_len
,
1884 const u8
*pmk_r0_name
)
1886 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1888 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1889 size_t packet_len
, key_len
;
1890 struct ft_rrb_seq f_seq
;
1891 int tsecs
, tusecs
, first
;
1892 struct wpabuf
*ft_pending_req_ies
;
1894 struct tlv_list req_enc
[] = {
1895 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1896 .data
= pmk_r0_name
},
1897 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1899 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1901 struct tlv_list req_auth
[] = {
1902 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1903 .data
= sm
->ft_pending_pull_nonce
},
1904 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1905 .data
= (u8
*) &f_seq
},
1906 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1907 .data
= sm
->r0kh_id
},
1908 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1909 .data
= f_r1kh_id
},
1910 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1913 if (sm
->ft_pending_pull_left_retries
<= 0)
1915 first
= sm
->ft_pending_pull_left_retries
==
1916 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1917 sm
->ft_pending_pull_left_retries
--;
1919 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1920 &r0kh
, &r0kh_wildcard
);
1922 /* Keep r0kh sufficiently long in the list for seq num check */
1923 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1924 1 + ftRRBseqTimeout
;
1926 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1927 } else if (r0kh_wildcard
) {
1928 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1929 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1930 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1931 r0kh_wildcard
->addr
,
1932 sm
->r0kh_id
, sm
->r0kh_id_len
,
1936 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1937 sm
->r0kh_id
, sm
->r0kh_id_len
);
1940 if (is_zero_ether_addr(r0kh
->addr
)) {
1941 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1942 sm
->r0kh_id
, sm
->r0kh_id_len
);
1945 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1946 wpa_printf(MSG_DEBUG
,
1947 "FT: R0KH-ID points to self - no matching key available");
1952 key_len
= sizeof(r0kh
->key
);
1954 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
1955 "address " MACSTR
, MAC2STR(r0kh
->addr
));
1957 if (r0kh
->seq
->rx
.num_last
== 0) {
1958 /* A sequence request will be sent out anyway when pull
1959 * response is received. Send it out now to avoid one RTT. */
1960 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
1961 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
1962 key_len
, NULL
, 0, NULL
, 0, NULL
);
1966 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
1967 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
1972 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
1973 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
1977 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
1978 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1979 &packet
, &packet_len
) < 0)
1982 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
1983 wpabuf_free(sm
->ft_pending_req_ies
);
1984 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
1985 if (!sm
->ft_pending_req_ies
) {
1990 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
1991 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
1992 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
1994 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1995 packet
, packet_len
);
2003 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
2004 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
2006 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2007 struct vlan_description vlan
;
2008 const u8
*identity
, *radius_cui
;
2009 size_t identity_len
, radius_cui_len
;
2010 int session_timeout
;
2011 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2012 SHA384_MAC_LEN
: PMK_LEN
;
2014 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2015 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2020 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2021 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2023 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2025 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2026 pmk_r0_name
, sm
->pairwise
, &vlan
, expires_in
,
2027 session_timeout
, identity
, identity_len
,
2028 radius_cui
, radius_cui_len
);
2032 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, const u8
*pmk
,
2033 struct wpa_ptk
*ptk
)
2035 u8 pmk_r0
[PMK_LEN_MAX
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2036 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2037 SHA384_MAC_LEN
: PMK_LEN
;
2038 size_t pmk_r1_len
= pmk_r0_len
;
2039 u8 pmk_r1
[PMK_LEN_MAX
];
2040 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2041 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
2042 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
2043 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
2044 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
2045 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
2046 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
2047 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
2048 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2049 struct vlan_description vlan
;
2050 const u8
*identity
, *radius_cui
;
2051 size_t identity_len
, radius_cui_len
;
2052 int session_timeout
;
2054 if (sm
->xxkey_len
== 0) {
2055 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
2060 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2061 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2066 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2067 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2069 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2071 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
2072 r0kh
, r0kh_len
, sm
->addr
,
2073 pmk_r0
, pmk_r0_name
,
2074 wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
)) < 0)
2076 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, pmk_r0_len
);
2077 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
2078 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2079 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2081 sm
->pairwise
, &vlan
, expires_in
,
2082 session_timeout
, identity
, identity_len
,
2083 radius_cui
, radius_cui_len
);
2085 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
, r1kh
, sm
->addr
,
2086 pmk_r1
, sm
->pmk_r1_name
) < 0)
2088 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, pmk_r1_len
);
2089 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
2091 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2092 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
, pmk_r1_len
,
2093 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
2094 expires_in
, session_timeout
, identity
,
2095 identity_len
, radius_cui
, radius_cui_len
);
2097 return wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2098 sm
->addr
, sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
2099 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
2103 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
2104 const u8
*addr
, int idx
, u8
*seq
)
2106 if (wpa_auth
->cb
->get_seqnum
== NULL
)
2108 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
2112 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2115 struct wpa_group
*gsm
= sm
->group
;
2116 size_t subelem_len
, pad_len
;
2123 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2125 kek_len
= sm
->PTK
.kek2_len
;
2128 kek_len
= sm
->PTK
.kek_len
;
2131 key_len
= gsm
->GTK_len
;
2132 if (key_len
> sizeof(keybuf
))
2136 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2139 pad_len
= key_len
% 8;
2141 pad_len
= 8 - pad_len
;
2142 if (key_len
+ pad_len
< 16)
2144 if (pad_len
&& key_len
< sizeof(keybuf
)) {
2145 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
2146 os_memset(keybuf
+ key_len
, 0, pad_len
);
2147 keybuf
[key_len
] = 0xdd;
2151 key
= gsm
->GTK
[gsm
->GN
- 1];
2154 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
2157 subelem_len
= 13 + key_len
+ 8;
2158 subelem
= os_zalloc(subelem_len
);
2159 if (subelem
== NULL
)
2162 subelem
[0] = FTIE_SUBELEM_GTK
;
2163 subelem
[1] = 11 + key_len
+ 8;
2164 /* Key ID in B0-B1 of Key Info */
2165 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
2166 subelem
[4] = gsm
->GTK_len
;
2167 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
2168 if (aes_wrap(kek
, kek_len
, key_len
/ 8, key
, subelem
+ 13)) {
2169 wpa_printf(MSG_DEBUG
,
2170 "FT: GTK subelem encryption failed: kek_len=%d",
2181 #ifdef CONFIG_IEEE80211W
2182 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2185 struct wpa_group
*gsm
= sm
->group
;
2191 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2193 kek_len
= sm
->PTK
.kek2_len
;
2196 kek_len
= sm
->PTK
.kek_len
;
2199 igtk_len
= wpa_cipher_key_len(sm
->wpa_auth
->conf
.group_mgmt_cipher
);
2201 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2203 subelem_len
= 1 + 1 + 2 + 6 + 1 + igtk_len
+ 8;
2204 subelem
= os_zalloc(subelem_len
);
2205 if (subelem
== NULL
)
2209 *pos
++ = FTIE_SUBELEM_IGTK
;
2210 *pos
++ = subelem_len
- 2;
2211 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
2213 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
2216 if (aes_wrap(kek
, kek_len
, igtk_len
/ 8,
2217 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
2218 wpa_printf(MSG_DEBUG
,
2219 "FT: IGTK subelem encryption failed: kek_len=%d",
2228 #endif /* CONFIG_IEEE80211W */
2231 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
2232 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
2233 const u8
*ies
, size_t ies_len
)
2235 struct ieee802_11_elems parse
;
2236 struct rsn_rdie
*rdie
;
2238 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
2240 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
2243 if (end
- pos
< (int) sizeof(*rdie
)) {
2244 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
2248 *pos
++ = WLAN_EID_RIC_DATA
;
2249 *pos
++ = sizeof(*rdie
);
2250 rdie
= (struct rsn_rdie
*) pos
;
2252 rdie
->descr_count
= 0;
2253 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2254 pos
+= sizeof(*rdie
);
2256 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2258 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2260 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2264 if (parse
.wmm_tspec
) {
2265 struct wmm_tspec_element
*tspec
;
2267 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2268 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2269 "(%d)", (int) parse
.wmm_tspec_len
);
2271 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2274 if (end
- pos
< (int) sizeof(*tspec
)) {
2275 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2278 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2281 tspec
= (struct wmm_tspec_element
*) pos
;
2282 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2286 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2289 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2290 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2291 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2293 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2294 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2296 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2298 /* TSPEC accepted; include updated TSPEC in response */
2299 rdie
->descr_count
= 1;
2300 pos
+= sizeof(struct wmm_tspec_element
);
2304 #endif /* NEED_AP_MLME */
2306 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2309 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2310 sizeof(struct wmm_tspec_element
));
2313 rdie
->status_code
= host_to_le16(res
);
2315 /* TSPEC accepted; include updated TSPEC in
2317 rdie
->descr_count
= 1;
2318 pos
+= sizeof(struct wmm_tspec_element
);
2324 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2325 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2330 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2331 const u8
*ric
, size_t ric_len
)
2333 const u8
*rpos
, *start
;
2334 const struct rsn_rdie
*rdie
;
2336 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2339 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2340 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2341 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2343 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2344 rpos
+= 2 + rpos
[1];
2347 while (rpos
+ 2 <= ric
+ ric_len
&&
2348 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2349 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2351 rpos
+= 2 + rpos
[1];
2353 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2355 start
, rpos
- start
);
2362 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2363 size_t max_len
, int auth_alg
,
2364 const u8
*req_ies
, size_t req_ies_len
)
2366 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2367 u8
*fte_mic
, *elem_count
;
2368 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2370 struct wpa_auth_config
*conf
;
2371 struct wpa_ft_ies parse
;
2373 u8
*anonce
, *snonce
;
2381 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
2382 conf
= &sm
->wpa_auth
->conf
;
2384 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2387 end
= pos
+ max_len
;
2389 if (auth_alg
== WLAN_AUTH_FT
) {
2391 * RSN (only present if this is a Reassociation Response and
2392 * part of a fast BSS transition)
2394 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2402 /* Mobility Domain Information */
2403 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2410 /* Fast BSS Transition Information */
2411 if (auth_alg
== WLAN_AUTH_FT
) {
2412 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2414 wpa_printf(MSG_DEBUG
,
2415 "FT: Failed to add GTK subelement");
2418 r0kh_id
= sm
->r0kh_id
;
2419 r0kh_id_len
= sm
->r0kh_id_len
;
2420 anonce
= sm
->ANonce
;
2421 snonce
= sm
->SNonce
;
2422 #ifdef CONFIG_IEEE80211W
2423 if (sm
->mgmt_frame_prot
) {
2427 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2429 wpa_printf(MSG_DEBUG
,
2430 "FT: Failed to add IGTK subelement");
2434 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2441 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2442 subelem_len
+= igtk_len
;
2445 #endif /* CONFIG_IEEE80211W */
2447 if (wpa_auth_uses_ocv(sm
)) {
2448 struct wpa_channel_info ci
;
2451 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
2452 wpa_printf(MSG_WARNING
,
2453 "Failed to get channel info for OCI element");
2458 subelem_len
+= 2 + OCV_OCI_LEN
;
2459 nbuf
= os_realloc(subelem
, subelem_len
);
2466 ocipos
= subelem
+ subelem_len
- 2 - OCV_OCI_LEN
;
2467 *ocipos
++ = FTIE_SUBELEM_OCI
;
2468 *ocipos
++ = OCV_OCI_LEN
;
2469 if (ocv_insert_oci(&ci
, &ocipos
) < 0) {
2474 #endif /* CONFIG_OCV */
2476 r0kh_id
= conf
->r0_key_holder
;
2477 r0kh_id_len
= conf
->r0_key_holder_len
;
2481 res
= wpa_write_ftie(conf
, use_sha384
, r0kh_id
, r0kh_id_len
,
2482 anonce
, snonce
, pos
, end
- pos
,
2483 subelem
, subelem_len
);
2492 struct rsn_ftie_sha384
*_ftie
=
2493 (struct rsn_ftie_sha384
*) (ftie
+ 2);
2495 fte_mic
= _ftie
->mic
;
2496 elem_count
= &_ftie
->mic_control
[1];
2498 struct rsn_ftie
*_ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2500 fte_mic
= _ftie
->mic
;
2501 elem_count
= &_ftie
->mic_control
[1];
2503 if (auth_alg
== WLAN_AUTH_FT
)
2504 *elem_count
= 3; /* Information element count */
2507 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
, use_sha384
) == 0
2509 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2511 if (auth_alg
== WLAN_AUTH_FT
)
2513 ieee802_11_ie_count(ric_start
,
2516 if (ric_start
== pos
)
2519 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2521 kck_len
= sm
->PTK
.kck2_len
;
2524 kck_len
= sm
->PTK
.kck_len
;
2526 if (auth_alg
== WLAN_AUTH_FT
&&
2527 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2528 mdie
, mdie_len
, ftie
, ftie_len
,
2530 ric_start
, ric_start
? pos
- ric_start
: 0,
2532 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2536 os_free(sm
->assoc_resp_ftie
);
2537 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2538 if (!sm
->assoc_resp_ftie
)
2540 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2546 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2548 enum wpa_alg alg
, const u8
*addr
, int idx
,
2549 u8
*key
, size_t key_len
)
2551 if (wpa_auth
->cb
->set_key
== NULL
)
2553 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2558 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
2563 /* MLME-SETKEYS.request(PTK) */
2564 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2565 klen
= wpa_cipher_key_len(sm
->pairwise
);
2566 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2567 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2568 "PTK configuration", sm
->pairwise
);
2572 if (sm
->tk_already_set
) {
2573 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2574 * PN in the driver */
2575 wpa_printf(MSG_DEBUG
,
2576 "FT: Do not re-install same PTK to the driver");
2580 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2581 * most likely without this.. At the moment, STA entry is added only
2582 * after association has been completed. This function will be called
2583 * again after association to get the PTK configured, but that could be
2584 * optimized by adding the STA entry earlier.
2586 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
2590 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2591 sm
->pairwise_set
= TRUE
;
2592 sm
->tk_already_set
= TRUE
;
2596 /* Derive PMK-R1 from PSK, check all available PSK */
2597 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2598 const u8
*req_pmk_r1_name
,
2599 u8
*out_pmk_r1
, int *out_pairwise
,
2600 struct vlan_description
*out_vlan
,
2601 const u8
**out_identity
, size_t *out_identity_len
,
2602 const u8
**out_radius_cui
,
2603 size_t *out_radius_cui_len
,
2604 int *out_session_timeout
)
2606 const u8
*pmk
= NULL
;
2607 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2608 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2609 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2610 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2611 const u8
*r0kh
= sm
->r0kh_id
;
2612 size_t r0kh_len
= sm
->r0kh_id_len
;
2613 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2614 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2615 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2618 pairwise
= sm
->pairwise
;
2621 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2626 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2628 pmk_r0
, pmk_r0_name
, 0) < 0 ||
2629 wpa_derive_pmk_r1(pmk_r0
, PMK_LEN
, pmk_r0_name
, r1kh
,
2630 sm
->addr
, pmk_r1
, pmk_r1_name
) < 0 ||
2631 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2632 WPA_PMK_NAME_LEN
) != 0)
2635 /* We found a PSK that matches the requested pmk_r1_name */
2636 wpa_printf(MSG_DEBUG
,
2637 "FT: Found PSK to generate PMK-R1 locally");
2638 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2640 *out_pairwise
= pairwise
;
2641 os_memcpy(sm
->PMK
, pmk
, PMK_LEN
);
2642 sm
->pmk_len
= PMK_LEN
;
2644 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2645 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2646 MACSTR
, MAC2STR(sm
->addr
));
2650 if (out_identity
&& out_identity_len
) {
2651 *out_identity_len
= wpa_ft_get_identity(
2652 sm
->wpa_auth
, sm
->addr
, out_identity
);
2655 if (out_radius_cui
&& out_radius_cui_len
) {
2656 *out_radius_cui_len
= wpa_ft_get_radius_cui(
2657 sm
->wpa_auth
, sm
->addr
, out_radius_cui
);
2660 if (out_session_timeout
) {
2661 *out_session_timeout
= wpa_ft_get_session_timeout(
2662 sm
->wpa_auth
, sm
->addr
);
2668 wpa_printf(MSG_DEBUG
,
2669 "FT: Did not find PSK to generate PMK-R1 locally");
2674 /* Detect the configuration the station asked for.
2675 * Required to detect FT-PSK and pairwise cipher.
2677 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2678 struct wpa_ft_ies
*parse
)
2680 int key_mgmt
, ciphers
;
2682 if (sm
->wpa_key_mgmt
)
2685 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2687 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2688 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2691 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2692 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2693 #ifdef CONFIG_SHA384
2694 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X_SHA384
)
2695 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X_SHA384
;
2696 #endif /* CONFIG_SHA384 */
2697 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2698 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2700 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2701 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2702 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2703 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2704 #endif /* CONFIG_FILS */
2705 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2707 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2709 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2712 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2718 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2719 struct wpa_state_machine
*sm
,
2720 const u8
*r0kh_id
, size_t r0kh_id_len
,
2721 const u8
*req_pmk_r0_name
,
2722 const u8
*req_pmk_r1_name
,
2723 u8
*out_pmk_r1
, int *out_pairwise
,
2724 struct vlan_description
*vlan
,
2725 const u8
**identity
, size_t *identity_len
,
2726 const u8
**radius_cui
,
2727 size_t *radius_cui_len
,
2728 int *out_session_timeout
)
2730 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2731 const struct wpa_ft_pmk_r0_sa
*r0
;
2732 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2734 int session_timeout
= 0;
2735 struct os_reltime now
;
2737 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2738 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2740 return -1; /* not our R0KH-ID */
2742 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2743 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2745 return -1; /* no matching PMKR0Name in local cache */
2747 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2749 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_len
, r0
->pmk_r0_name
,
2750 conf
->r1_key_holder
,
2751 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2753 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, r0
->pmk_r0_len
);
2754 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2756 os_get_reltime(&now
);
2758 expires_in
= r0
->expiration
- now
.sec
;
2760 if (r0
->session_timeout
)
2761 session_timeout
= r0
->session_timeout
- now
.sec
;
2763 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, r0
->pmk_r0_len
,
2765 sm
->pairwise
, r0
->vlan
, expires_in
, session_timeout
,
2766 r0
->identity
, r0
->identity_len
,
2767 r0
->radius_cui
, r0
->radius_cui_len
);
2769 *out_pairwise
= sm
->pairwise
;
2774 os_memset(vlan
, 0, sizeof(*vlan
));
2777 if (identity
&& identity_len
) {
2778 *identity
= r0
->identity
;
2779 *identity_len
= r0
->identity_len
;
2782 if (radius_cui
&& radius_cui_len
) {
2783 *radius_cui
= r0
->radius_cui
;
2784 *radius_cui_len
= r0
->radius_cui_len
;
2787 *out_session_timeout
= session_timeout
;
2793 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2794 const u8
*ies
, size_t ies_len
,
2795 u8
**resp_ies
, size_t *resp_ies_len
)
2797 struct rsn_mdie
*mdie
;
2798 u8 pmk_r1
[PMK_LEN_MAX
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2799 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2800 struct wpa_auth_config
*conf
;
2801 struct wpa_ft_ies parse
;
2805 int pairwise
, session_timeout
= 0;
2806 struct vlan_description vlan
;
2807 const u8
*identity
, *radius_cui
;
2808 size_t identity_len
= 0, radius_cui_len
= 0;
2815 sm
->pmk_r1_name_valid
= 0;
2816 conf
= &sm
->wpa_auth
->conf
;
2818 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2821 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, -1)) {
2822 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2823 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2825 use_sha384
= wpa_key_mgmt_sha384(parse
.key_mgmt
);
2826 pmk_r1_len
= use_sha384
? SHA384_MAC_LEN
: PMK_LEN
;
2828 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2829 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2830 os_memcmp(mdie
->mobility_domain
,
2831 sm
->wpa_auth
->conf
.mobility_domain
,
2832 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2833 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2834 return WLAN_STATUS_INVALID_MDIE
;
2838 struct rsn_ftie_sha384
*ftie
;
2840 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
2841 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2842 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2843 return WLAN_STATUS_INVALID_FTIE
;
2846 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2848 struct rsn_ftie
*ftie
;
2850 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2851 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2852 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2853 return WLAN_STATUS_INVALID_FTIE
;
2856 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2859 if (parse
.r0kh_id
== NULL
) {
2860 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2861 return WLAN_STATUS_INVALID_FTIE
;
2864 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2865 parse
.r0kh_id
, parse
.r0kh_id_len
);
2866 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2867 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2869 if (parse
.rsn_pmkid
== NULL
) {
2870 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2871 return WLAN_STATUS_INVALID_PMKID
;
2874 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2875 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2877 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2878 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2879 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2880 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2881 pmk_r1_name
, use_sha384
) < 0)
2882 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2883 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2884 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2886 if (conf
->ft_psk_generate_local
&&
2887 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2888 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
2889 &vlan
, &identity
, &identity_len
,
2890 &radius_cui
, &radius_cui_len
,
2891 &session_timeout
) < 0)
2892 return WLAN_STATUS_INVALID_PMKID
;
2893 wpa_printf(MSG_DEBUG
,
2894 "FT: Generated PMK-R1 for FT-PSK locally");
2895 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2896 pmk_r1
, &pmk_r1_len
, &pairwise
, &vlan
,
2897 &identity
, &identity_len
, &radius_cui
,
2898 &radius_cui_len
, &session_timeout
) < 0) {
2899 wpa_printf(MSG_DEBUG
,
2900 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2901 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2902 parse
.r0kh_id
, parse
.r0kh_id_len
,
2904 pmk_r1_name
, pmk_r1
, &pairwise
,
2905 &vlan
, &identity
, &identity_len
,
2906 &radius_cui
, &radius_cui_len
,
2907 &session_timeout
) == 0) {
2908 wpa_printf(MSG_DEBUG
,
2909 "FT: Generated PMK-R1 based on local PMK-R0");
2910 goto pmk_r1_derived
;
2913 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2914 wpa_printf(MSG_DEBUG
,
2915 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2916 return WLAN_STATUS_INVALID_PMKID
;
2919 return -1; /* Status pending */
2921 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2925 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, pmk_r1_len
);
2926 sm
->pmk_r1_name_valid
= 1;
2927 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2929 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2930 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2932 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2935 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2936 sm
->SNonce
, WPA_NONCE_LEN
);
2937 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2938 sm
->ANonce
, WPA_NONCE_LEN
);
2940 if (wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2941 sm
->addr
, sm
->wpa_auth
->addr
, pmk_r1_name
,
2942 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
2944 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2946 sm
->pairwise
= pairwise
;
2947 sm
->PTK_valid
= TRUE
;
2948 sm
->tk_already_set
= FALSE
;
2949 wpa_ft_install_ptk(sm
);
2951 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2952 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
2953 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2955 if (wpa_ft_set_identity(sm
->wpa_auth
, sm
->addr
,
2956 identity
, identity_len
) < 0 ||
2957 wpa_ft_set_radius_cui(sm
->wpa_auth
, sm
->addr
,
2958 radius_cui
, radius_cui_len
) < 0) {
2959 wpa_printf(MSG_DEBUG
, "FT: Failed to configure identity/CUI");
2960 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2962 wpa_ft_set_session_timeout(sm
->wpa_auth
, sm
->addr
, session_timeout
);
2964 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
2965 2 + FT_R1KH_ID_LEN
+ 200;
2966 *resp_ies
= os_zalloc(buflen
);
2967 if (*resp_ies
== NULL
)
2971 end
= *resp_ies
+ buflen
;
2973 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
2978 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
2983 ret
= wpa_write_ftie(conf
, use_sha384
, parse
.r0kh_id
, parse
.r0kh_id_len
,
2984 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
2989 *resp_ies_len
= pos
- *resp_ies
;
2991 return WLAN_STATUS_SUCCESS
;
2995 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2999 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
3000 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
3001 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
3002 u16 auth_transaction
, u16 status
,
3003 const u8
*ies
, size_t ies_len
),
3008 size_t resp_ies_len
;
3012 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
3013 "WPA SM not available");
3017 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
3018 " BSSID=" MACSTR
" transaction=%d",
3019 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
3020 sm
->ft_pending_cb
= cb
;
3021 sm
->ft_pending_cb_ctx
= ctx
;
3022 sm
->ft_pending_auth_transaction
= auth_transaction
;
3023 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3024 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
3027 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
3032 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
3033 " auth_transaction=%d status=%d",
3034 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
3035 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3036 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
3037 resp_ies
, resp_ies_len
);
3042 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
3045 struct wpa_ft_ies parse
;
3046 struct rsn_mdie
*mdie
;
3047 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
3048 size_t mic_len
= 16;
3053 const u8
*anonce
, *snonce
, *fte_mic
;
3057 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3059 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
3061 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
3063 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, use_sha384
) < 0) {
3064 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
3065 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3068 if (parse
.rsn
== NULL
) {
3069 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
3070 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3073 if (parse
.rsn_pmkid
== NULL
) {
3074 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
3075 return WLAN_STATUS_INVALID_PMKID
;
3078 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
3080 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
3081 "with the PMKR1Name derived from auth request");
3082 return WLAN_STATUS_INVALID_PMKID
;
3085 mdie
= (struct rsn_mdie
*) parse
.mdie
;
3086 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
3087 os_memcmp(mdie
->mobility_domain
,
3088 sm
->wpa_auth
->conf
.mobility_domain
,
3089 MOBILITY_DOMAIN_ID_LEN
) != 0) {
3090 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
3091 return WLAN_STATUS_INVALID_MDIE
;
3095 struct rsn_ftie_sha384
*ftie
;
3097 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
3098 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3099 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3100 return WLAN_STATUS_INVALID_FTIE
;
3103 anonce
= ftie
->anonce
;
3104 snonce
= ftie
->snonce
;
3105 fte_elem_count
= ftie
->mic_control
[1];
3106 fte_mic
= ftie
->mic
;
3108 struct rsn_ftie
*ftie
;
3110 ftie
= (struct rsn_ftie
*) parse
.ftie
;
3111 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3112 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3113 return WLAN_STATUS_INVALID_FTIE
;
3116 anonce
= ftie
->anonce
;
3117 snonce
= ftie
->snonce
;
3118 fte_elem_count
= ftie
->mic_control
[1];
3119 fte_mic
= ftie
->mic
;
3122 if (os_memcmp(snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
3123 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
3124 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
3125 snonce
, WPA_NONCE_LEN
);
3126 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
3127 sm
->SNonce
, WPA_NONCE_LEN
);
3128 return WLAN_STATUS_INVALID_FTIE
;
3131 if (os_memcmp(anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
3132 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
3133 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
3134 anonce
, WPA_NONCE_LEN
);
3135 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
3136 sm
->ANonce
, WPA_NONCE_LEN
);
3137 return WLAN_STATUS_INVALID_FTIE
;
3141 if (parse
.r0kh_id
== NULL
) {
3142 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
3143 return WLAN_STATUS_INVALID_FTIE
;
3146 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
3147 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
3149 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
3150 "the current R0KH-ID");
3151 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
3152 parse
.r0kh_id
, parse
.r0kh_id_len
);
3153 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
3154 sm
->r0kh_id
, sm
->r0kh_id_len
);
3155 return WLAN_STATUS_INVALID_FTIE
;
3158 if (parse
.r1kh_id
== NULL
) {
3159 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
3160 return WLAN_STATUS_INVALID_FTIE
;
3163 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
3164 FT_R1KH_ID_LEN
) != 0) {
3165 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
3167 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
3168 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
3169 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
3170 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
3171 return WLAN_STATUS_INVALID_FTIE
;
3174 if (parse
.rsn_pmkid
== NULL
||
3175 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
3177 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
3178 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
3179 return WLAN_STATUS_INVALID_PMKID
;
3184 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
3185 if (fte_elem_count
!= count
) {
3186 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
3187 "Control: received %u expected %u",
3188 fte_elem_count
, count
);
3189 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3192 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
3194 kck_len
= sm
->PTK
.kck2_len
;
3197 kck_len
= sm
->PTK
.kck_len
;
3199 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
3200 parse
.mdie
- 2, parse
.mdie_len
+ 2,
3201 parse
.ftie
- 2, parse
.ftie_len
+ 2,
3202 parse
.rsn
- 2, parse
.rsn_len
+ 2,
3203 parse
.ric
, parse
.ric_len
,
3205 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
3206 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3209 if (os_memcmp_const(mic
, fte_mic
, mic_len
) != 0) {
3210 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
3211 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
3212 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
3213 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
3215 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
3216 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
3217 parse
.mdie
- 2, parse
.mdie_len
+ 2);
3218 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
3219 parse
.ftie
- 2, parse
.ftie_len
+ 2);
3220 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
3221 parse
.rsn
- 2, parse
.rsn_len
+ 2);
3222 return WLAN_STATUS_INVALID_FTIE
;
3226 if (wpa_auth_uses_ocv(sm
)) {
3227 struct wpa_channel_info ci
;
3231 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
3232 wpa_printf(MSG_WARNING
,
3233 "Failed to get channel info to validate received OCI in (Re)Assoc Request");
3234 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3237 if (get_sta_tx_parameters(sm
,
3238 channel_width_to_int(ci
.chanwidth
),
3239 ci
.seg1_idx
, &tx_chanwidth
,
3241 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3243 if (ocv_verify_tx_params(parse
.oci
, parse
.oci_len
, &ci
,
3244 tx_chanwidth
, tx_seg1_idx
) != 0) {
3245 wpa_printf(MSG_WARNING
, "%s", ocv_errorstr
);
3246 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3249 #endif /* CONFIG_OCV */
3251 return WLAN_STATUS_SUCCESS
;
3255 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
3257 const u8
*sta_addr
, *target_ap
;
3261 struct ft_rrb_frame
*frame
;
3267 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3268 * FT Request action frame body[variable]
3272 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
3273 "(len=%lu)", (unsigned long) len
);
3278 sta_addr
= data
+ 2;
3279 target_ap
= data
+ 8;
3283 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
3284 " Target AP=" MACSTR
" Action=%d)",
3285 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
3287 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
3288 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
3289 "STA=" MACSTR
" STA-Address=" MACSTR
,
3290 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
3295 * Do some sanity checking on the target AP address (not own and not
3296 * broadcast. This could be extended to filter based on a list of known
3297 * APs in the MD (if such a list were configured).
3299 if ((target_ap
[0] & 0x01) ||
3300 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
3301 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
3306 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
3308 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
3309 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
3313 /* RRB - Forward action frame to the target AP */
3314 frame
= os_malloc(sizeof(*frame
) + len
);
3317 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3318 frame
->packet_type
= FT_PACKET_REQUEST
;
3319 frame
->action_length
= host_to_le16(len
);
3320 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
3321 os_memcpy(frame
+ 1, data
, len
);
3323 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
3324 sizeof(*frame
) + len
);
3331 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
3332 u16 auth_transaction
, u16 resp
,
3333 const u8
*ies
, size_t ies_len
)
3335 struct wpa_state_machine
*sm
= ctx
;
3336 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
3338 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
3339 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
3343 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
3344 const u8
*current_ap
, const u8
*sta_addr
,
3345 const u8
*body
, size_t len
)
3347 struct wpa_state_machine
*sm
;
3350 size_t resp_ies_len
;
3353 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
3355 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
3360 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
3362 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
3363 sm
->ft_pending_cb_ctx
= sm
;
3364 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
3365 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3366 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
3369 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
3374 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
3375 resp_ies
, resp_ies_len
);
3381 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
3382 const u8
*current_ap
, const u8
*sta_addr
,
3383 u16 status
, const u8
*resp_ies
,
3384 size_t resp_ies_len
)
3386 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
3388 struct ft_rrb_frame
*frame
;
3391 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
3392 " CurrentAP=" MACSTR
" status=%d",
3393 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
3394 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3396 /* RRB - Forward action frame response to the Current AP */
3399 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3400 * Status_Code[2] FT Request action frame body[variable]
3402 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
3404 frame
= os_malloc(sizeof(*frame
) + rlen
);
3407 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3408 frame
->packet_type
= FT_PACKET_RESPONSE
;
3409 frame
->action_length
= host_to_le16(rlen
);
3410 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
3411 pos
= (u8
*) (frame
+ 1);
3412 *pos
++ = WLAN_ACTION_FT
;
3413 *pos
++ = 2; /* Action: Response */
3414 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
3416 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
3418 WPA_PUT_LE16(pos
, status
);
3421 os_memcpy(pos
, resp_ies
, resp_ies_len
);
3423 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
3424 sizeof(*frame
) + rlen
);
3431 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
3432 const struct tlv_list
*tlvs
,
3433 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3434 const u8
*r1kh_id
, const u8
*s1kh_id
,
3435 const struct tlv_list
*tlv_auth
,
3436 const u8
*src_addr
, u8 type
,
3437 u8
**packet
, size_t *packet_len
)
3439 u8 pmk_r1
[PMK_LEN_MAX
];
3440 size_t pmk_r1_len
= pmk_r0
->pmk_r0_len
;
3441 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3442 u8 f_pairwise
[sizeof(le16
)];
3443 u8 f_expires_in
[sizeof(le16
)];
3444 u8 f_session_timeout
[sizeof(le32
)];
3446 int session_timeout
;
3447 struct os_reltime now
;
3449 struct tlv_list sess_tlv
[] = {
3450 { .type
= FT_RRB_PMK_R1
, .len
= pmk_r1_len
,
3452 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3453 .data
= pmk_r1_name
},
3454 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3455 .data
= f_pairwise
},
3456 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3457 .data
= f_expires_in
},
3458 { .type
= FT_RRB_IDENTITY
, .len
= pmk_r0
->identity_len
,
3459 .data
= pmk_r0
->identity
},
3460 { .type
= FT_RRB_RADIUS_CUI
, .len
= pmk_r0
->radius_cui_len
,
3461 .data
= pmk_r0
->radius_cui
},
3462 { .type
= FT_RRB_SESSION_TIMEOUT
,
3463 .len
= sizeof(f_session_timeout
),
3464 .data
= f_session_timeout
},
3465 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3468 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_len
,
3469 pmk_r0
->pmk_r0_name
, r1kh_id
,
3470 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3472 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1 (for peer AP)",
3473 pmk_r1
, pmk_r1_len
);
3474 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name (for peer AP)",
3475 pmk_r1_name
, WPA_PMK_NAME_LEN
);
3476 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3478 os_get_reltime(&now
);
3479 if (pmk_r0
->expiration
> now
.sec
)
3480 expires_in
= pmk_r0
->expiration
- now
.sec
;
3481 else if (pmk_r0
->expiration
)
3485 WPA_PUT_LE16(f_expires_in
, expires_in
);
3487 if (pmk_r0
->session_timeout
> now
.sec
)
3488 session_timeout
= pmk_r0
->session_timeout
- now
.sec
;
3489 else if (pmk_r0
->session_timeout
)
3490 session_timeout
= 1;
3492 session_timeout
= 0;
3493 WPA_PUT_LE32(f_session_timeout
, session_timeout
);
3495 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3496 pmk_r0
->vlan
, src_addr
, type
,
3497 packet
, packet_len
);
3499 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
3505 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3507 const u8
*enc
, size_t enc_len
,
3508 const u8
*auth
, size_t auth_len
,
3511 const char *msgtype
= "pull request";
3512 u8
*plain
= NULL
, *packet
= NULL
;
3513 size_t plain_len
= 0, packet_len
= 0;
3514 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3518 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3519 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3520 size_t f_pmk_r0_name_len
;
3521 const struct wpa_ft_pmk_r0_sa
*r0
;
3523 struct tlv_list resp
[2];
3524 struct tlv_list resp_auth
[5];
3525 struct ft_rrb_seq f_seq
;
3527 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3529 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3530 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3532 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3533 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3537 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3538 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3540 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3543 key_len
= sizeof(r1kh
->key
);
3544 } else if (r1kh_wildcard
) {
3545 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3546 key
= r1kh_wildcard
->key
;
3547 key_len
= sizeof(r1kh_wildcard
->key
);
3552 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3553 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3555 seq_ret
= FT_RRB_SEQ_DROP
;
3557 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3558 auth
, auth_len
, msgtype
, no_defer
);
3559 if (!no_defer
&& r1kh_wildcard
&&
3560 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3561 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3562 seq_ret
= FT_RRB_SEQ_DEFER
;
3565 if (seq_ret
== FT_RRB_SEQ_DROP
)
3568 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3569 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3570 &plain
, &plain_len
) < 0)
3574 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3576 wpa_auth
->conf
.rkh_pos_timeout
);
3580 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3581 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3582 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3583 enc
, enc_len
, auth
, auth_len
,
3584 &wpa_ft_rrb_rx_pull
);
3588 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3590 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3591 wpa_auth
->conf
.rkh_pos_timeout
);
3593 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3594 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3597 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3598 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3600 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3601 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3605 resp
[0].type
= FT_RRB_S1KH_ID
;
3606 resp
[0].len
= f_s1kh_id_len
;
3607 resp
[0].data
= f_s1kh_id
;
3608 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3610 resp
[1].data
= NULL
;
3612 resp_auth
[0].type
= FT_RRB_NONCE
;
3613 resp_auth
[0].len
= f_nonce_len
;
3614 resp_auth
[0].data
= f_nonce
;
3615 resp_auth
[1].type
= FT_RRB_SEQ
;
3616 resp_auth
[1].len
= sizeof(f_seq
);
3617 resp_auth
[1].data
= (u8
*) &f_seq
;
3618 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3619 resp_auth
[2].len
= f_r0kh_id_len
;
3620 resp_auth
[2].data
= f_r0kh_id
;
3621 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3622 resp_auth
[3].len
= f_r1kh_id_len
;
3623 resp_auth
[3].data
= f_r1kh_id
;
3624 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3625 resp_auth
[4].len
= 0;
3626 resp_auth
[4].data
= NULL
;
3628 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0) {
3629 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3630 ret
= wpa_ft_rrb_build(key
, key_len
, resp
, NULL
, resp_auth
,
3631 NULL
, wpa_auth
->addr
,
3632 FT_PACKET_R0KH_R1KH_RESP
,
3633 &packet
, &packet_len
);
3635 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
,
3636 f_s1kh_id
, resp_auth
, wpa_auth
->addr
,
3637 FT_PACKET_R0KH_R1KH_RESP
,
3638 &packet
, &packet_len
);
3642 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3643 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3654 /* @returns 0 on success
3656 * -2 if FR_RRB_PAIRWISE is missing
3658 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3659 const u8
*src_addr
, u8 type
,
3660 const u8
*enc
, size_t enc_len
,
3661 const u8
*auth
, size_t auth_len
,
3662 const char *msgtype
, u8
*s1kh_id_out
,
3663 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3665 const u8
*enc
, size_t enc_len
,
3666 const u8
*auth
, size_t auth_len
,
3670 size_t plain_len
= 0;
3671 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3675 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3676 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3677 const u8
*f_expires_in
;
3678 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3679 const u8
*f_identity
, *f_radius_cui
;
3680 const u8
*f_session_timeout
;
3681 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3682 size_t f_expires_in_len
;
3683 size_t f_identity_len
, f_radius_cui_len
;
3684 size_t f_session_timeout_len
;
3688 int session_timeout
;
3689 struct vlan_description vlan
;
3692 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3693 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3695 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3696 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3698 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3699 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3703 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3707 key_len
= sizeof(r0kh
->key
);
3708 } else if (r0kh_wildcard
) {
3709 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3710 key
= r0kh_wildcard
->key
;
3711 key_len
= sizeof(r0kh_wildcard
->key
);
3716 seq_ret
= FT_RRB_SEQ_DROP
;
3718 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3719 auth
, auth_len
, msgtype
,
3722 if (cb
&& r0kh_wildcard
&&
3723 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3724 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3725 seq_ret
= FT_RRB_SEQ_DEFER
;
3728 if (seq_ret
== FT_RRB_SEQ_DROP
)
3731 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3732 src_addr
, type
, &plain
, &plain_len
) < 0)
3736 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3737 f_r0kh_id
, f_r0kh_id_len
,
3738 wpa_auth
->conf
.rkh_pos_timeout
);
3742 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3743 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3744 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3745 enc
, enc_len
, auth
, auth_len
, cb
);
3749 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3751 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3752 wpa_auth
->conf
.rkh_pos_timeout
);
3754 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3755 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3758 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3761 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3762 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3765 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3766 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3767 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
3769 pmk_r1_len
= PMK_LEN
;
3770 if (wpa_ft_rrb_get_tlv(plain
, plain_len
, FT_RRB_PMK_R1
, &f_pmk_r1_len
,
3772 (f_pmk_r1_len
== PMK_LEN
|| f_pmk_r1_len
== SHA384_MAC_LEN
))
3773 pmk_r1_len
= f_pmk_r1_len
;
3774 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, pmk_r1_len
);
3775 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, pmk_r1_len
);
3777 pairwise
= WPA_GET_LE16(f_pairwise
);
3779 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
3782 expires_in
= WPA_GET_LE16(f_expires_in
);
3786 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
3789 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
3790 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
3791 wpa_ft_rrb_dump(plain
, plain_len
);
3795 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
3796 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
3798 RRB_GET_OPTIONAL(FT_RRB_IDENTITY
, identity
, msgtype
, -1);
3800 wpa_hexdump_ascii(MSG_DEBUG
, "FT: Identity", f_identity
,
3803 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI
, radius_cui
, msgtype
, -1);
3805 wpa_hexdump_ascii(MSG_DEBUG
, "FT: CUI", f_radius_cui
,
3808 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT
, session_timeout
, msgtype
,
3810 if (f_session_timeout
)
3811 session_timeout
= WPA_GET_LE32(f_session_timeout
);
3813 session_timeout
= 0;
3814 wpa_printf(MSG_DEBUG
, "FT: session_timeout %d", session_timeout
);
3816 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, pmk_r1_len
,
3818 pairwise
, &vlan
, expires_in
, session_timeout
,
3819 f_identity
, f_identity_len
, f_radius_cui
,
3820 f_radius_cui_len
) < 0)
3826 os_memset(plain
, 0, plain_len
);
3835 static void ft_finish_pull(struct wpa_state_machine
*sm
)
3839 size_t resp_ies_len
;
3842 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
3845 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
3846 wpabuf_len(sm
->ft_pending_req_ies
),
3847 &resp_ies
, &resp_ies_len
);
3849 /* this loop is broken by ft_pending_pull_left_retries */
3850 wpa_printf(MSG_DEBUG
,
3851 "FT: Callback postponed until response is available");
3854 wpabuf_free(sm
->ft_pending_req_ies
);
3855 sm
->ft_pending_req_ies
= NULL
;
3857 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
3858 " - status %u", MAC2STR(sm
->addr
), status
);
3860 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
3861 sm
->ft_pending_auth_transaction
+ 1, status
,
3862 resp_ies
, resp_ies_len
);
3867 struct ft_get_sta_ctx
{
3870 struct wpa_state_machine
*sm
;
3874 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3876 struct ft_get_sta_ctx
*info
= ctx
;
3878 if ((info
->s1kh_id
&&
3879 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3880 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3881 FT_RRB_NONCE_LEN
) != 0 ||
3882 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3891 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3893 const u8
*enc
, size_t enc_len
,
3894 const u8
*auth
, size_t auth_len
,
3897 const char *msgtype
= "pull response";
3899 struct ft_get_sta_ctx ctx
;
3900 u8 s1kh_id
[ETH_ALEN
];
3904 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3906 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3907 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3909 os_memset(&ctx
, 0, sizeof(ctx
));
3910 ctx
.nonce
= f_nonce
;
3911 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3912 /* nonce not found */
3913 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3917 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3918 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3919 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3929 ctx
.s1kh_id
= s1kh_id
;
3930 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3931 wpa_printf(MSG_DEBUG
,
3932 "FT: Response to a pending pull request for " MACSTR
,
3933 MAC2STR(ctx
.sm
->addr
));
3934 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3936 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3937 ft_finish_pull(ctx
.sm
);
3945 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
3947 const u8
*enc
, size_t enc_len
,
3948 const u8
*auth
, size_t auth_len
, int no_defer
)
3950 const char *msgtype
= "push";
3952 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
3954 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3955 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
3956 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
3963 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
3964 const u8
*src_addr
, int type
,
3965 const u8
*enc
, size_t enc_len
,
3966 const u8
*auth
, size_t auth_len
,
3967 struct ft_remote_seq
**rkh_seq
,
3968 u8
**key
, size_t *key_len
,
3969 struct ft_remote_r0kh
**r0kh_out
,
3970 struct ft_remote_r1kh
**r1kh_out
,
3971 struct ft_remote_r0kh
**r0kh_wildcard_out
,
3972 struct ft_remote_r1kh
**r1kh_wildcard_out
)
3974 struct ft_remote_r0kh
*r0kh
= NULL
;
3975 struct ft_remote_r1kh
*r1kh
= NULL
;
3976 const u8
*f_r0kh_id
, *f_r1kh_id
;
3977 size_t f_r0kh_id_len
, f_r1kh_id_len
;
3978 int to_r0kh
, to_r1kh
;
3980 size_t plain_len
= 0;
3981 struct ft_remote_r0kh
*r0kh_wildcard
;
3982 struct ft_remote_r1kh
*r1kh_wildcard
;
3984 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3985 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3987 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
3988 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
3990 if (to_r0kh
&& to_r1kh
) {
3991 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
3995 if (!to_r0kh
&& !to_r1kh
) {
3996 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
4001 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
4002 &r0kh
, &r0kh_wildcard
);
4003 if (!r0kh_wildcard
&&
4004 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4005 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
4006 f_r0kh_id
, f_r0kh_id_len
);
4011 *key_len
= sizeof(r0kh
->key
);
4013 *key
= r0kh_wildcard
->key
;
4014 *key_len
= sizeof(r0kh_wildcard
->key
);
4019 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
4021 if (!r1kh_wildcard
&&
4022 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4023 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
4024 f_r1kh_id
, FT_R1KH_ID_LEN
);
4029 *key_len
= sizeof(r1kh
->key
);
4031 *key
= r1kh_wildcard
->key
;
4032 *key_len
= sizeof(r1kh_wildcard
->key
);
4036 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
4037 src_addr
, type
, &plain
, &plain_len
) < 0)
4044 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
4045 src_addr
, f_r0kh_id
,
4051 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
4052 *rkh_seq
= r0kh
->seq
;
4055 if (r0kh_wildcard_out
)
4056 *r0kh_wildcard_out
= r0kh_wildcard
;
4061 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
4062 src_addr
, f_r1kh_id
,
4067 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
4068 *rkh_seq
= r1kh
->seq
;
4071 if (r1kh_wildcard_out
)
4072 *r1kh_wildcard_out
= r1kh_wildcard
;
4081 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
4083 const u8
*enc
, size_t enc_len
,
4084 const u8
*auth
, size_t auth_len
,
4088 struct ft_rrb_seq f_seq
;
4089 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
4090 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
4091 struct ft_remote_seq
*rkh_seq
= NULL
;
4092 u8
*packet
= NULL
, *key
= NULL
;
4093 size_t packet_len
= 0, key_len
= 0;
4094 struct tlv_list seq_resp_auth
[5];
4096 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
4098 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
4099 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4100 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
4103 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
4104 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
4106 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4107 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4109 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
4110 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4114 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
4115 seq_resp_auth
[0].len
= f_nonce_len
;
4116 seq_resp_auth
[0].data
= f_nonce
;
4117 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
4118 seq_resp_auth
[1].len
= sizeof(f_seq
);
4119 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
4120 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
4121 seq_resp_auth
[2].len
= f_r0kh_id_len
;
4122 seq_resp_auth
[2].data
= f_r0kh_id
;
4123 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
4124 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
4125 seq_resp_auth
[3].data
= f_r1kh_id
;
4126 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
4127 seq_resp_auth
[4].len
= 0;
4128 seq_resp_auth
[4].data
= NULL
;
4130 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
4131 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4132 &packet
, &packet_len
) < 0)
4135 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
4136 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
4146 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
4148 const u8
*enc
, size_t enc_len
,
4149 const u8
*auth
, size_t auth_len
,
4154 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
4155 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
4156 const u8
*f_nonce
, *f_seq
;
4157 size_t f_nonce_len
, f_seq_len
;
4158 struct ft_remote_seq
*rkh_seq
= NULL
;
4159 struct ft_remote_item
*item
;
4160 struct os_reltime now
, now_remote
;
4162 const struct ft_rrb_seq
*msg_both
;
4163 u32 msg_dom
, msg_seq
;
4165 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
4167 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4168 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4169 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
4170 &r1kh_wildcard
) < 0)
4173 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
4174 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
4178 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
4180 if (os_memcmp_const(f_nonce
, item
->nonce
,
4181 FT_RRB_NONCE_LEN
) != 0 ||
4182 os_get_reltime(&now
) < 0 ||
4183 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
4190 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
4195 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
4196 wpa_auth
->conf
.rkh_pos_timeout
);
4198 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
4202 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
4203 wpa_auth
->conf
.rkh_pos_timeout
);
4205 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
4208 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
4209 auth_len
, "seq response", 1);
4210 if (seq_ret
== FT_RRB_SEQ_OK
) {
4211 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
4212 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
4213 auth_len
, "seq response");
4215 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
4217 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
4219 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
4221 msg_dom
= le_to_host32(msg_both
->dom
);
4222 msg_seq
= le_to_host32(msg_both
->seq
);
4223 now_remote
.sec
= le_to_host32(msg_both
->ts
);
4224 now_remote
.usec
= 0;
4226 rkh_seq
->rx
.num_last
= 2;
4227 rkh_seq
->rx
.dom
= msg_dom
;
4228 rkh_seq
->rx
.offsetidx
= 0;
4229 /* Accept some older, possibly cached packets as well */
4230 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
4231 dl_list_len(&rkh_seq
->rx
.queue
);
4232 rkh_seq
->rx
.last
[1] = msg_seq
;
4234 /* local time - offset = remote time
4235 * <=> local time - remote time = offset */
4236 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
4239 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
4247 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4248 const u8
*data
, size_t data_len
)
4250 struct ft_rrb_frame
*frame
;
4252 const u8
*pos
, *end
, *start
;
4254 const u8
*sta_addr
, *target_ap_addr
;
4256 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
4259 if (data_len
< sizeof(*frame
)) {
4260 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
4261 (unsigned long) data_len
);
4266 frame
= (struct ft_rrb_frame
*) pos
;
4267 pos
+= sizeof(*frame
);
4269 alen
= le_to_host16(frame
->action_length
);
4270 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
4271 "action_length=%d ap_address=" MACSTR
,
4272 frame
->frame_type
, frame
->packet_type
, alen
,
4273 MAC2STR(frame
->ap_address
));
4275 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
4276 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
4277 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
4278 "unrecognized type %d", frame
->frame_type
);
4282 if (alen
> data_len
- sizeof(*frame
)) {
4283 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
4288 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
4290 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
4291 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
4292 "room for Action Frame body); alen=%lu",
4293 (unsigned long) alen
);
4299 if (*pos
!= WLAN_ACTION_FT
) {
4300 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
4309 target_ap_addr
= pos
;
4311 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
4312 MACSTR
" target_ap_addr=" MACSTR
,
4313 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
4315 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
4316 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
4319 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
4320 "RRB Request", action
);
4324 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
4325 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
4326 "RRB Request does not match with own "
4331 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
4332 sta_addr
, pos
, end
- pos
) < 0)
4334 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
4337 if (end
- pos
< 2) {
4338 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
4339 "code in RRB Response");
4342 status_code
= WPA_GET_LE16(pos
);
4345 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
4346 "(status_code=%d)", status_code
);
4348 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
4351 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
4352 "packet_type %d", frame
->packet_type
);
4357 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
4365 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4366 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
4369 const u8
*auth
, *enc
;
4373 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
4374 MACSTR
, MAC2STR(src_addr
));
4375 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
4377 if (is_multicast_ether_addr(src_addr
)) {
4378 wpa_printf(MSG_DEBUG
,
4379 "FT: RRB-OUI received frame from multicast address "
4380 MACSTR
, MAC2STR(src_addr
));
4384 if (is_multicast_ether_addr(dst_addr
)) {
4385 wpa_printf(MSG_DEBUG
,
4386 "FT: RRB-OUI received frame from remote AP " MACSTR
4387 " to multicast address " MACSTR
,
4388 MAC2STR(src_addr
), MAC2STR(dst_addr
));
4392 if (data_len
< sizeof(u16
)) {
4393 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4397 alen
= WPA_GET_LE16(data
);
4398 if (data_len
< sizeof(u16
) + alen
) {
4399 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4403 auth
= data
+ sizeof(u16
);
4404 enc
= data
+ sizeof(u16
) + alen
;
4405 elen
= data_len
- sizeof(u16
) - alen
;
4407 switch (oui_suffix
) {
4408 case FT_PACKET_R0KH_R1KH_PULL
:
4409 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4412 case FT_PACKET_R0KH_R1KH_RESP
:
4413 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4416 case FT_PACKET_R0KH_R1KH_PUSH
:
4417 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4420 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
4421 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4424 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
4425 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
4432 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
4433 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
4434 struct ft_remote_r1kh
*r1kh
,
4439 struct ft_rrb_seq f_seq
;
4440 struct tlv_list push
[] = {
4441 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
4443 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
4444 .data
= pmk_r0
->pmk_r0_name
},
4445 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4447 struct tlv_list push_auth
[] = {
4448 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
4449 .data
= (u8
*) &f_seq
},
4450 { .type
= FT_RRB_R0KH_ID
,
4451 .len
= wpa_auth
->conf
.r0_key_holder_len
,
4452 .data
= wpa_auth
->conf
.r0_key_holder
},
4453 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
4455 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4458 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
4459 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4463 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
4464 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
4465 FT_PACKET_R0KH_R1KH_PUSH
,
4466 &packet
, &packet_len
) < 0)
4469 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4470 packet
, packet_len
);
4477 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
4479 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
4480 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
4481 struct ft_remote_r1kh
*r1kh
;
4483 if (!wpa_auth
->conf
.pmk_r1_push
)
4485 if (!wpa_auth
->conf
.r1kh_list
)
4488 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
4489 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4496 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4498 r0
->pmk_r1_pushed
= 1;
4500 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4501 "for STA " MACSTR
, MAC2STR(addr
));
4503 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4504 if (is_zero_ether_addr(r1kh
->addr
) ||
4505 is_zero_ether_addr(r1kh
->id
))
4507 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4509 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4513 #endif /* CONFIG_IEEE80211R_AP */