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"
28 #include "pmksa_cache_auth.h"
31 #ifdef CONFIG_IEEE80211R_AP
33 const unsigned int ftRRBseqTimeout
= 10;
34 const unsigned int ftRRBmaxQueueLen
= 100;
37 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
38 const u8
*current_ap
, const u8
*sta_addr
,
39 u16 status
, const u8
*resp_ies
,
41 static void ft_finish_pull(struct wpa_state_machine
*sm
);
42 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
43 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
53 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
54 * @key: AES-SIV key for AEAD
55 * @key_len: Length of key in octets
56 * @enc: Pointer to encrypted TLVs
57 * @enc_len: Length of encrypted TLVs in octets
58 * @auth: Pointer to authenticated TLVs
59 * @auth_len: Length of authenticated TLVs in octets
60 * @src_addr: MAC address of the frame sender
61 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
62 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
63 * needs to be freed by the caller if not NULL;
64 * will only be returned on success
65 * @plain_len: Pointer to return the length of the allocated plaintext buffer
67 * Returns: 0 on success, -1 on error
69 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
70 const u8
*enc
, size_t enc_len
,
71 const u8
*auth
, const size_t auth_len
,
72 const u8
*src_addr
, u8 type
,
73 u8
**plain
, size_t *plain_size
)
75 const u8
*ad
[3] = { src_addr
, auth
, &type
};
76 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
78 wpa_printf(MSG_DEBUG
, "FT(RRB): src_addr=" MACSTR
" type=%u",
79 MAC2STR(src_addr
), type
);
80 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
81 wpa_hexdump(MSG_DEBUG
, "FT(RRB): encrypted TLVs", enc
, enc_len
);
82 wpa_hexdump(MSG_DEBUG
, "FT(RRB): authenticated TLVs", auth
, auth_len
);
84 if (!key
) { /* skip decryption */
85 *plain
= os_memdup(enc
, enc_len
);
86 if (enc_len
> 0 && !*plain
)
89 *plain_size
= enc_len
;
97 if (enc_len
< AES_BLOCK_SIZE
)
100 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
104 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
106 if (enc_len
< AES_BLOCK_SIZE
+ 2)
109 /* Try to work around Ethernet devices that add extra
110 * two octet padding even if the frame is longer than
111 * the minimum Ethernet frame. */
113 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
118 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
119 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
120 *plain
, *plain_size
);
127 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
133 /* get first tlv record in packet matching type
134 * @data (decrypted) packet
135 * @return 0 on success else -1
137 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
138 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
140 const struct ft_rrb_tlv
*f
;
146 type16
= host_to_le16(type
);
148 while (left
>= sizeof(*f
)) {
149 f
= (const struct ft_rrb_tlv
*) plain
;
153 len
= le_to_host16(f
->len
);
156 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
160 if (f
->type
== type16
) {
174 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
176 const struct ft_rrb_tlv
*f
;
182 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
183 while (left
>= sizeof(*f
)) {
184 f
= (const struct ft_rrb_tlv
*) plain
;
188 len
= le_to_host16(f
->len
);
190 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
191 le_to_host16(f
->type
), len
);
194 wpa_printf(MSG_DEBUG
,
195 "FT: RRB message truncated: left %zu bytes, need %zu",
200 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
207 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
209 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
213 static int cmp_int(const void *a
, const void *b
)
223 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
224 struct vlan_description
*vlan
)
226 struct ft_rrb_tlv
*f
;
235 os_memset(vlan
, 0, sizeof(*vlan
));
237 while (left
>= sizeof(*f
)) {
238 f
= (struct ft_rrb_tlv
*) plain
;
243 len
= le_to_host16(f
->len
);
244 type
= le_to_host16(f
->type
);
247 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
251 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
254 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
255 wpa_printf(MSG_DEBUG
,
256 "FT: RRB VLAN_UNTAGGED invalid length");
260 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
261 wpa_printf(MSG_DEBUG
,
262 "FT: RRB VLAN_TAGGED invalid length");
266 while (len
>= sizeof(le16
)) {
267 vlan_id
= WPA_GET_LE16(plain
);
268 plain
+= sizeof(le16
);
269 left
-= sizeof(le16
);
272 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
273 wpa_printf(MSG_DEBUG
,
274 "FT: RRB VLAN ID invalid %d",
279 if (type
== FT_RRB_VLAN_UNTAGGED
)
280 vlan
->untagged
= vlan_id
;
282 if (type
== FT_RRB_VLAN_TAGGED
&&
283 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
284 vlan
->tagged
[taggedidx
] = vlan_id
;
286 } else if (type
== FT_RRB_VLAN_TAGGED
) {
287 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
297 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
299 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
305 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
313 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
314 tlv_len
+= sizeof(struct ft_rrb_tlv
);
315 tlv_len
+= tlvs
[i
].len
;
322 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
327 struct ft_rrb_tlv
*hdr
;
335 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
336 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
338 tlv_len
+= sizeof(*hdr
);
339 hdr
= (struct ft_rrb_tlv
*) pos
;
340 hdr
->type
= host_to_le16(tlvs
[i
].type
);
341 hdr
->len
= host_to_le16(tlvs
[i
].len
);
342 pos
= start
+ tlv_len
;
344 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
346 if (tlvs
[i
].len
== 0)
348 tlv_len
+= tlvs
[i
].len
;
349 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
350 pos
= start
+ tlv_len
;
357 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
362 if (!vlan
|| !vlan
->notempty
)
365 if (vlan
->untagged
) {
366 tlv_len
+= sizeof(struct ft_rrb_tlv
);
367 tlv_len
+= sizeof(le16
);
370 tlv_len
+= sizeof(struct ft_rrb_tlv
);
371 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
372 tlv_len
+= sizeof(le16
);
378 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
379 u8
*start
, u8
*endpos
)
383 struct ft_rrb_tlv
*hdr
;
386 if (!vlan
|| !vlan
->notempty
)
390 if (vlan
->untagged
) {
391 tlv_len
+= sizeof(*hdr
);
392 if (start
+ tlv_len
> endpos
)
394 hdr
= (struct ft_rrb_tlv
*) pos
;
395 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
396 hdr
->len
= host_to_le16(sizeof(le16
));
397 pos
= start
+ tlv_len
;
399 tlv_len
+= sizeof(le16
);
400 if (start
+ tlv_len
> endpos
)
402 WPA_PUT_LE16(pos
, vlan
->untagged
);
403 pos
= start
+ tlv_len
;
406 if (!vlan
->tagged
[0])
409 tlv_len
+= sizeof(*hdr
);
410 if (start
+ tlv_len
> endpos
)
412 hdr
= (struct ft_rrb_tlv
*) pos
;
413 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
414 len
= 0; /* len is computed below */
415 pos
= start
+ tlv_len
;
417 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
418 tlv_len
+= sizeof(le16
);
419 if (start
+ tlv_len
> endpos
)
422 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
423 pos
= start
+ tlv_len
;
426 hdr
->len
= host_to_le16(len
);
432 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
433 const struct tlv_list
*tlvs2
,
434 const struct vlan_description
*vlan
,
435 u8
**plain
, size_t *plain_len
)
440 tlv_len
= wpa_ft_tlv_len(tlvs1
);
441 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
442 tlv_len
+= wpa_ft_vlan_len(vlan
);
444 *plain_len
= tlv_len
;
445 *plain
= os_zalloc(tlv_len
);
447 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
452 endpos
= *plain
+ tlv_len
;
453 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
454 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
455 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
459 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
473 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
474 const u8
*plain
, const size_t plain_len
,
475 const u8
*auth
, const size_t auth_len
,
476 const u8
*src_addr
, u8 type
, u8
*enc
)
478 const u8
*ad
[3] = { src_addr
, auth
, &type
};
479 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
481 wpa_printf(MSG_DEBUG
, "FT(RRB): src_addr=" MACSTR
" type=%u",
482 MAC2STR(src_addr
), type
);
483 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
485 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
486 wpa_hexdump(MSG_DEBUG
, "FT(RRB): authenticated TLVs", auth
, auth_len
);
489 /* encryption not needed, return plaintext as packet */
490 os_memcpy(enc
, plain
, plain_len
);
491 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
492 3, ad
, ad_len
, enc
) < 0) {
493 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
496 wpa_hexdump(MSG_DEBUG
, "FT(RRB): encrypted TLVs",
497 enc
, plain_len
+ AES_BLOCK_SIZE
);
504 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
505 * @key: AES-SIV key for AEAD
506 * @key_len: Length of key in octets
507 * @tlvs_enc0: First set of to-be-encrypted TLVs
508 * @tlvs_enc1: Second set of to-be-encrypted TLVs
509 * @tlvs_auth: Set of to-be-authenticated TLVs
510 * @src_addr: MAC address of the frame sender
511 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
512 * @packet Pointer to return the pointer to the allocated packet buffer;
513 * needs to be freed by the caller if not null;
514 * will only be returned on success
515 * @packet_len: Pointer to return the length of the allocated buffer in octets
516 * Returns: 0 on success, -1 on error
518 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
519 const struct tlv_list
*tlvs_enc0
,
520 const struct tlv_list
*tlvs_enc1
,
521 const struct tlv_list
*tlvs_auth
,
522 const struct vlan_description
*vlan
,
523 const u8
*src_addr
, u8 type
,
524 u8
**packet
, size_t *packet_len
)
526 u8
*plain
= NULL
, *auth
= NULL
, *pos
, *tmp
;
527 size_t plain_len
= 0, auth_len
= 0;
532 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
535 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
538 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
540 *packet_len
+= AES_BLOCK_SIZE
;
541 #define RRB_MIN_MSG_LEN 64
542 if (*packet_len
< RRB_MIN_MSG_LEN
) {
543 pad_len
= RRB_MIN_MSG_LEN
- *packet_len
;
544 if (pad_len
< sizeof(struct ft_rrb_tlv
))
545 pad_len
= sizeof(struct ft_rrb_tlv
);
546 wpa_printf(MSG_DEBUG
,
547 "FT: Pad message to minimum Ethernet frame length (%d --> %d)",
548 (int) *packet_len
, (int) (*packet_len
+ pad_len
));
549 *packet_len
+= pad_len
;
550 tmp
= os_realloc(auth
, auth_len
+ pad_len
);
554 pos
= auth
+ auth_len
;
555 WPA_PUT_LE16(pos
, FT_RRB_LAST_EMPTY
);
557 WPA_PUT_LE16(pos
, pad_len
- sizeof(struct ft_rrb_tlv
));
559 os_memset(pos
, 0, pad_len
- sizeof(struct ft_rrb_tlv
));
563 *packet
= os_zalloc(*packet_len
);
568 WPA_PUT_LE16(pos
, auth_len
);
570 os_memcpy(pos
, auth
, auth_len
);
572 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
573 auth_len
, src_addr
, type
, pos
) < 0)
575 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB frame payload", *packet
, *packet_len
);
580 bin_clear_free(plain
, plain_len
);
584 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
594 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
595 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
596 &f_##field##_len, &f_##field) < 0 || \
597 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
598 wpa_printf(MSG_INFO, "FT: Missing required " #field \
599 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
600 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
605 #define RRB_GET(type, field, txt, checklength) \
606 RRB_GET_SRC(plain, type, field, txt, checklength)
607 #define RRB_GET_AUTH(type, field, txt, checklength) \
608 RRB_GET_SRC(auth, type, field, txt, checklength)
610 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
611 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
612 &f_##field##_len, &f_##field) < 0 || \
613 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
614 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
615 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
616 f_##field##_len = 0; \
621 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
622 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
623 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
624 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
626 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
627 const u8
*data
, size_t data_len
)
629 if (wpa_auth
->cb
->send_ether
== NULL
)
631 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
632 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
637 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
638 const u8
*dst
, u8 oui_suffix
,
639 const u8
*data
, size_t data_len
)
641 if (!wpa_auth
->cb
->send_oui
)
643 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
" (len=%u)",
644 oui_suffix
, MAC2STR(dst
), (unsigned int) data_len
);
645 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
650 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
651 const u8
*dst
, const u8
*data
, size_t data_len
)
653 if (wpa_auth
->cb
->send_ft_action
== NULL
)
655 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
660 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
661 const u8
*addr
, const u8
*p2p_dev_addr
,
664 if (wpa_auth
->cb
->get_psk
== NULL
)
666 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
667 prev_psk
, NULL
, NULL
);
671 static struct wpa_state_machine
*
672 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
674 if (wpa_auth
->cb
->add_sta
== NULL
)
676 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
680 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
681 const u8
*sta_addr
, struct vlan_description
*vlan
)
683 if (!wpa_auth
->cb
->set_vlan
)
685 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
689 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
690 const u8
*sta_addr
, struct vlan_description
*vlan
)
692 if (!wpa_auth
->cb
->get_vlan
)
694 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
699 wpa_ft_set_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
700 const u8
*identity
, size_t identity_len
)
702 if (!wpa_auth
->cb
->set_identity
)
704 return wpa_auth
->cb
->set_identity(wpa_auth
->cb_ctx
, sta_addr
, identity
,
710 wpa_ft_get_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
714 if (!wpa_auth
->cb
->get_identity
)
716 return wpa_auth
->cb
->get_identity(wpa_auth
->cb_ctx
, sta_addr
, buf
);
721 wpa_ft_set_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
722 const u8
*radius_cui
, size_t radius_cui_len
)
724 if (!wpa_auth
->cb
->set_radius_cui
)
726 return wpa_auth
->cb
->set_radius_cui(wpa_auth
->cb_ctx
, sta_addr
,
727 radius_cui
, radius_cui_len
);
732 wpa_ft_get_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
736 if (!wpa_auth
->cb
->get_radius_cui
)
738 return wpa_auth
->cb
->get_radius_cui(wpa_auth
->cb_ctx
, sta_addr
, buf
);
743 wpa_ft_set_session_timeout(struct wpa_authenticator
*wpa_auth
,
744 const u8
*sta_addr
, int session_timeout
)
746 if (!wpa_auth
->cb
->set_session_timeout
)
748 wpa_auth
->cb
->set_session_timeout(wpa_auth
->cb_ctx
, sta_addr
,
754 wpa_ft_get_session_timeout(struct wpa_authenticator
*wpa_auth
,
757 if (!wpa_auth
->cb
->get_session_timeout
)
759 return wpa_auth
->cb
->get_session_timeout(wpa_auth
->cb_ctx
, sta_addr
);
763 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
765 u8
*tspec_ie
, size_t tspec_ielen
)
767 if (wpa_auth
->cb
->add_tspec
== NULL
) {
768 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
771 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
777 static int wpa_channel_info(struct wpa_authenticator
*wpa_auth
,
778 struct wpa_channel_info
*ci
)
780 if (!wpa_auth
->cb
->channel_info
)
782 return wpa_auth
->cb
->channel_info(wpa_auth
->cb_ctx
, ci
);
784 #endif /* CONFIG_OCV */
787 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
791 if (len
< 2 + sizeof(struct rsn_mdie
))
794 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
795 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
796 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
797 pos
+= MOBILITY_DOMAIN_ID_LEN
;
799 if (conf
->ft_over_ds
)
800 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
807 int wpa_write_ftie(struct wpa_auth_config
*conf
, int use_sha384
,
808 const u8
*r0kh_id
, size_t r0kh_id_len
,
809 const u8
*anonce
, const u8
*snonce
,
810 u8
*buf
, size_t len
, const u8
*subelem
,
811 size_t subelem_len
, int rsnxe_used
)
813 u8
*pos
= buf
, *ielen
;
814 size_t hdrlen
= use_sha384
? sizeof(struct rsn_ftie_sha384
) :
815 sizeof(struct rsn_ftie
);
817 if (len
< 2 + hdrlen
+ 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
821 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
825 struct rsn_ftie_sha384
*hdr
= (struct rsn_ftie_sha384
*) pos
;
827 os_memset(hdr
, 0, sizeof(*hdr
));
829 WPA_PUT_LE16(hdr
->mic_control
, !!rsnxe_used
);
831 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
833 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
835 struct rsn_ftie
*hdr
= (struct rsn_ftie
*) pos
;
837 os_memset(hdr
, 0, sizeof(*hdr
));
839 WPA_PUT_LE16(hdr
->mic_control
, !!rsnxe_used
);
841 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
843 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
846 /* Optional Parameters */
847 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
848 *pos
++ = FT_R1KH_ID_LEN
;
849 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
850 pos
+= FT_R1KH_ID_LEN
;
853 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
854 *pos
++ = r0kh_id_len
;
855 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
860 os_memcpy(pos
, subelem
, subelem_len
);
864 *ielen
= pos
- buf
- 2;
870 /* A packet to be handled after seq response */
871 struct ft_remote_item
{
874 u8 nonce
[FT_RRB_NONCE_LEN
];
875 struct os_reltime nonce_ts
;
877 u8 src_addr
[ETH_ALEN
];
882 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
884 const u8
*enc
, size_t enc_len
,
885 const u8
*auth
, size_t auth_len
,
890 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
892 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
893 dl_list_del(&item
->list
);
894 bin_clear_free(item
->enc
, item
->enc_len
);
900 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
901 struct ft_remote_seq
*rkh_seq
, int cb
)
903 struct ft_remote_item
*item
, *n
;
905 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
906 struct ft_remote_item
, list
) {
908 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
909 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
910 wpa_ft_rrb_seq_free(item
);
915 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
917 struct ft_remote_item
*item
= timeout_ctx
;
919 wpa_ft_rrb_seq_free(item
);
924 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
925 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
926 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
927 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
928 const u8
*enc
, size_t enc_len
,
929 const u8
*auth
, size_t auth_len
,
930 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
932 const u8
*enc
, size_t enc_len
,
933 const u8
*auth
, size_t auth_len
,
936 struct ft_remote_item
*item
= NULL
;
939 struct tlv_list seq_req_auth
[] = {
940 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
941 .data
= NULL
/* to be filled: item->nonce */ },
942 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
944 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
946 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
949 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
950 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
954 wpa_printf(MSG_DEBUG
, "FT: Send sequence number request from " MACSTR
956 MAC2STR(wpa_auth
->addr
), MAC2STR(src_addr
));
957 item
= os_zalloc(sizeof(*item
));
961 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
964 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
965 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
969 if (os_get_reltime(&item
->nonce_ts
) < 0)
972 if (enc
&& enc_len
> 0) {
973 item
->enc
= os_memdup(enc
, enc_len
);
974 item
->enc_len
= enc_len
;
979 if (auth
&& auth_len
> 0) {
980 item
->auth
= os_memdup(auth
, auth_len
);
981 item
->auth_len
= auth_len
;
986 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
989 seq_req_auth
[0].data
= item
->nonce
;
991 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
992 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
993 &packet
, &packet_len
) < 0) {
994 item
= NULL
; /* some other seq resp might still accept this */
998 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
1000 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
1001 packet
, packet_len
);
1007 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
1009 os_free(item
->auth
);
1010 bin_clear_free(item
->enc
, item
->enc_len
);
1018 #define FT_RRB_SEQ_OK 0
1019 #define FT_RRB_SEQ_DROP 1
1020 #define FT_RRB_SEQ_DEFER 2
1023 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1024 const u8
*enc
, size_t enc_len
,
1025 const u8
*auth
, size_t auth_len
,
1026 const char *msgtype
, int no_defer
)
1030 const struct ft_rrb_seq
*msg_both
;
1031 u32 msg_seq
, msg_off
, rkh_off
;
1032 struct os_reltime now
;
1035 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1036 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
1037 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1039 if (rkh_seq
->rx
.num_last
== 0) {
1040 /* first packet from remote */
1044 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
1045 /* remote might have rebooted */
1049 if (os_get_reltime(&now
) == 0) {
1050 u32 msg_ts_now_remote
, msg_ts_off
;
1051 struct os_reltime now_remote
;
1053 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
1054 msg_ts_now_remote
= now_remote
.sec
;
1055 msg_ts_off
= le_to_host32(msg_both
->ts
) -
1056 (msg_ts_now_remote
- ftRRBseqTimeout
);
1057 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
1061 msg_seq
= le_to_host32(msg_both
->seq
);
1062 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1063 msg_off
= msg_seq
- rkh_off
;
1064 if (msg_off
> 0xC0000000)
1065 goto out
; /* too old message, drop it */
1067 if (msg_off
<= 0x40000000) {
1068 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1069 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
1070 goto out
; /* duplicate message, drop it */
1073 return FT_RRB_SEQ_OK
;
1080 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
1081 MACSTR
, msgtype
, MAC2STR(src_addr
));
1083 return FT_RRB_SEQ_DEFER
;
1085 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
1086 msgtype
, MAC2STR(src_addr
));
1088 return FT_RRB_SEQ_DROP
;
1093 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
1094 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1095 const u8
*auth
, size_t auth_len
,
1096 const char *msgtype
)
1100 const struct ft_rrb_seq
*msg_both
;
1101 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
1105 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1106 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1108 msg_seq
= le_to_host32(msg_both
->seq
);
1110 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
1111 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
1112 rkh_seq
->rx
.num_last
++;
1116 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1117 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1118 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
1119 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
1120 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
1123 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
1124 rkh_seq
->rx
.offsetidx
= minidx
;
1128 /* RRB_GET_AUTH should never fail here as
1129 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1130 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
1134 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
1135 struct ft_rrb_seq
*f_seq
)
1137 struct os_reltime now
;
1139 if (os_get_reltime(&now
) < 0)
1142 if (!rkh_seq
->tx
.dom
) {
1143 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1144 sizeof(rkh_seq
->tx
.seq
))) {
1145 wpa_printf(MSG_ERROR
,
1146 "FT: Failed to get random data for sequence number initialization");
1147 rkh_seq
->tx
.seq
= now
.usec
;
1149 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1150 sizeof(rkh_seq
->tx
.dom
))) {
1151 wpa_printf(MSG_ERROR
,
1152 "FT: Failed to get random data for sequence number initialization");
1153 rkh_seq
->tx
.dom
= now
.usec
;
1155 rkh_seq
->tx
.dom
|= 1;
1158 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1159 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1160 f_seq
->ts
= host_to_le32(now
.sec
);
1168 struct wpa_ft_pmk_r0_sa
{
1169 struct dl_list list
;
1170 u8 pmk_r0
[PMK_LEN_MAX
];
1172 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1174 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1175 struct vlan_description
*vlan
;
1176 os_time_t expiration
; /* 0 for no expiration */
1178 size_t identity_len
;
1180 size_t radius_cui_len
;
1181 os_time_t session_timeout
; /* 0 for no expiration */
1182 /* TODO: radius_class, EAP type */
1186 struct wpa_ft_pmk_r1_sa
{
1187 struct dl_list list
;
1188 u8 pmk_r1
[PMK_LEN_MAX
];
1190 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1192 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1193 struct vlan_description
*vlan
;
1195 size_t identity_len
;
1197 size_t radius_cui_len
;
1198 os_time_t session_timeout
; /* 0 for no expiration */
1199 /* TODO: radius_class, EAP type */
1202 struct wpa_ft_pmk_cache
{
1203 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1204 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1208 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1209 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1212 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1217 dl_list_del(&r0
->list
);
1218 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1220 os_memset(r0
->pmk_r0
, 0, PMK_LEN_MAX
);
1222 os_free(r0
->identity
);
1223 os_free(r0
->radius_cui
);
1228 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1230 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1231 struct os_reltime now
;
1233 int session_timeout
;
1235 os_get_reltime(&now
);
1240 expires_in
= r0
->expiration
- now
.sec
;
1241 session_timeout
= r0
->session_timeout
- now
.sec
;
1242 /* conditions to remove from cache:
1243 * a) r0->expiration is set and hit
1245 * b) r0->session_timeout is set and hit
1247 if ((!r0
->expiration
|| expires_in
> 0) &&
1248 (!r0
->session_timeout
|| session_timeout
> 0)) {
1249 wpa_printf(MSG_ERROR
,
1250 "FT: %s() called for non-expired entry %p",
1252 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1253 if (r0
->expiration
&& expires_in
> 0)
1254 eloop_register_timeout(expires_in
+ 1, 0,
1255 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1256 if (r0
->session_timeout
&& session_timeout
> 0)
1257 eloop_register_timeout(session_timeout
+ 1, 0,
1258 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1262 wpa_ft_free_pmk_r0(r0
);
1266 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1271 dl_list_del(&r1
->list
);
1272 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1274 os_memset(r1
->pmk_r1
, 0, PMK_LEN_MAX
);
1276 os_free(r1
->identity
);
1277 os_free(r1
->radius_cui
);
1282 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1284 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1286 wpa_ft_free_pmk_r1(r1
);
1290 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1292 struct wpa_ft_pmk_cache
*cache
;
1294 cache
= os_zalloc(sizeof(*cache
));
1296 dl_list_init(&cache
->pmk_r0
);
1297 dl_list_init(&cache
->pmk_r1
);
1304 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1306 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1307 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1309 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1310 struct wpa_ft_pmk_r0_sa
, list
)
1311 wpa_ft_free_pmk_r0(r0
);
1313 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1314 struct wpa_ft_pmk_r1_sa
, list
)
1315 wpa_ft_free_pmk_r1(r1
);
1321 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1322 const u8
*spa
, const u8
*pmk_r0
,
1324 const u8
*pmk_r0_name
, int pairwise
,
1325 const struct vlan_description
*vlan
,
1326 int expires_in
, int session_timeout
,
1327 const u8
*identity
, size_t identity_len
,
1328 const u8
*radius_cui
, size_t radius_cui_len
)
1330 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1331 struct wpa_ft_pmk_r0_sa
*r0
;
1332 struct os_reltime now
;
1334 /* TODO: add limit on number of entries in cache */
1335 os_get_reltime(&now
);
1337 r0
= os_zalloc(sizeof(*r0
));
1341 os_memcpy(r0
->pmk_r0
, pmk_r0
, pmk_r0_len
);
1342 r0
->pmk_r0_len
= pmk_r0_len
;
1343 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1344 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1345 r0
->pairwise
= pairwise
;
1347 r0
->expiration
= now
.sec
+ expires_in
;
1348 if (vlan
&& vlan
->notempty
) {
1349 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1351 bin_clear_free(r0
, sizeof(*r0
));
1357 r0
->identity
= os_malloc(identity_len
);
1359 os_memcpy(r0
->identity
, identity
, identity_len
);
1360 r0
->identity_len
= identity_len
;
1364 r0
->radius_cui
= os_malloc(radius_cui_len
);
1365 if (r0
->radius_cui
) {
1366 os_memcpy(r0
->radius_cui
, radius_cui
, radius_cui_len
);
1367 r0
->radius_cui_len
= radius_cui_len
;
1370 if (session_timeout
> 0)
1371 r0
->session_timeout
= now
.sec
+ session_timeout
;
1373 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1375 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1377 if (session_timeout
> 0)
1378 eloop_register_timeout(session_timeout
+ 1, 0,
1379 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1385 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1386 const u8
*spa
, const u8
*pmk_r0_name
,
1387 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1389 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1390 struct wpa_ft_pmk_r0_sa
*r0
;
1391 struct os_reltime now
;
1393 os_get_reltime(&now
);
1394 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1395 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1396 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1397 WPA_PMK_NAME_LEN
) == 0) {
1408 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1409 const u8
*spa
, const u8
*pmk_r1
,
1411 const u8
*pmk_r1_name
, int pairwise
,
1412 const struct vlan_description
*vlan
,
1413 int expires_in
, int session_timeout
,
1414 const u8
*identity
, size_t identity_len
,
1415 const u8
*radius_cui
, size_t radius_cui_len
)
1417 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1418 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1419 struct wpa_ft_pmk_r1_sa
*r1
;
1420 struct os_reltime now
;
1422 /* TODO: limit on number of entries in cache */
1423 os_get_reltime(&now
);
1425 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1426 expires_in
= max_expires_in
;
1428 r1
= os_zalloc(sizeof(*r1
));
1432 os_memcpy(r1
->pmk_r1
, pmk_r1
, pmk_r1_len
);
1433 r1
->pmk_r1_len
= pmk_r1_len
;
1434 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1435 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1436 r1
->pairwise
= pairwise
;
1437 if (vlan
&& vlan
->notempty
) {
1438 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1440 bin_clear_free(r1
, sizeof(*r1
));
1446 r1
->identity
= os_malloc(identity_len
);
1448 os_memcpy(r1
->identity
, identity
, identity_len
);
1449 r1
->identity_len
= identity_len
;
1453 r1
->radius_cui
= os_malloc(radius_cui_len
);
1454 if (r1
->radius_cui
) {
1455 os_memcpy(r1
->radius_cui
, radius_cui
, radius_cui_len
);
1456 r1
->radius_cui_len
= radius_cui_len
;
1459 if (session_timeout
> 0)
1460 r1
->session_timeout
= now
.sec
+ session_timeout
;
1462 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1465 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1467 if (session_timeout
> 0)
1468 eloop_register_timeout(session_timeout
+ 1, 0,
1469 wpa_ft_expire_pmk_r1
, r1
, NULL
);
1475 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1476 const u8
*spa
, const u8
*pmk_r1_name
,
1477 u8
*pmk_r1
, size_t *pmk_r1_len
, int *pairwise
,
1478 struct vlan_description
*vlan
,
1479 const u8
**identity
, size_t *identity_len
,
1480 const u8
**radius_cui
, size_t *radius_cui_len
,
1481 int *session_timeout
)
1483 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1484 struct wpa_ft_pmk_r1_sa
*r1
;
1485 struct os_reltime now
;
1487 os_get_reltime(&now
);
1489 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1490 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1491 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1492 WPA_PMK_NAME_LEN
) == 0) {
1493 os_memcpy(pmk_r1
, r1
->pmk_r1
, r1
->pmk_r1_len
);
1494 *pmk_r1_len
= r1
->pmk_r1_len
;
1496 *pairwise
= r1
->pairwise
;
1497 if (vlan
&& r1
->vlan
)
1499 if (vlan
&& !r1
->vlan
)
1500 os_memset(vlan
, 0, sizeof(*vlan
));
1501 if (identity
&& identity_len
) {
1502 *identity
= r1
->identity
;
1503 *identity_len
= r1
->identity_len
;
1505 if (radius_cui
&& radius_cui_len
) {
1506 *radius_cui
= r1
->radius_cui
;
1507 *radius_cui_len
= r1
->radius_cui_len
;
1509 if (session_timeout
&& r1
->session_timeout
> now
.sec
)
1510 *session_timeout
= r1
->session_timeout
-
1512 else if (session_timeout
&& r1
->session_timeout
)
1513 *session_timeout
= 1;
1514 else if (session_timeout
)
1515 *session_timeout
= 0;
1524 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1529 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1531 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1535 dl_list_init(&r0kh
->seq
->rx
.queue
);
1541 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1542 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1543 struct ft_remote_r0kh
**r0kh_out
,
1544 struct ft_remote_r0kh
**r0kh_wildcard
)
1546 struct ft_remote_r0kh
*r0kh
;
1548 *r0kh_wildcard
= NULL
;
1551 if (wpa_auth
->conf
.r0kh_list
)
1552 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1555 for (; r0kh
; r0kh
= r0kh
->next
) {
1556 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1557 *r0kh_wildcard
= r0kh
;
1558 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1559 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1563 if (!*r0kh_out
&& !*r0kh_wildcard
)
1564 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1566 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1571 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1576 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1578 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1582 dl_list_init(&r1kh
->seq
->rx
.queue
);
1588 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1589 const u8
*f_r1kh_id
,
1590 struct ft_remote_r1kh
**r1kh_out
,
1591 struct ft_remote_r1kh
**r1kh_wildcard
)
1593 struct ft_remote_r1kh
*r1kh
;
1595 *r1kh_wildcard
= NULL
;
1598 if (wpa_auth
->conf
.r1kh_list
)
1599 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1602 for (; r1kh
; r1kh
= r1kh
->next
) {
1603 if (is_zero_ether_addr(r1kh
->addr
) &&
1604 is_zero_ether_addr(r1kh
->id
))
1605 *r1kh_wildcard
= r1kh
;
1607 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1611 if (!*r1kh_out
&& !*r1kh_wildcard
)
1612 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1614 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1619 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1620 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1622 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1623 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1624 f_r0kh_id_len
) != 0)
1631 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1632 const u8
*f_r1kh_id
)
1634 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1635 FT_R1KH_ID_LEN
) != 0)
1642 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1644 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1645 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1647 if (!wpa_auth
->conf
.r0kh_list
)
1650 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1651 if (r0kh
== timeout_ctx
)
1658 prev
->next
= r0kh
->next
;
1660 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1662 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1668 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1669 struct ft_remote_r0kh
*r0kh
, int timeout
)
1672 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1677 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1678 struct ft_remote_r0kh
*r0kh
, int timeout
)
1680 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1683 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1688 static struct ft_remote_r0kh
*
1689 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1690 struct ft_remote_r0kh
*r0kh_wildcard
,
1691 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1694 struct ft_remote_r0kh
*r0kh
;
1696 if (!wpa_auth
->conf
.r0kh_list
)
1699 r0kh
= os_zalloc(sizeof(*r0kh
));
1704 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1706 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1707 id_len
= FT_R0KH_ID_MAX_LEN
;
1708 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1709 r0kh
->id_len
= id_len
;
1711 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1713 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1714 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1717 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1720 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1727 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1729 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1730 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1732 if (!wpa_auth
->conf
.r1kh_list
)
1735 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1736 if (r1kh
== timeout_ctx
)
1743 prev
->next
= r1kh
->next
;
1745 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1747 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1753 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1754 struct ft_remote_r1kh
*r1kh
, int timeout
)
1757 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1762 static struct ft_remote_r1kh
*
1763 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1764 struct ft_remote_r1kh
*r1kh_wildcard
,
1765 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1767 struct ft_remote_r1kh
*r1kh
;
1769 if (!wpa_auth
->conf
.r1kh_list
)
1772 r1kh
= os_zalloc(sizeof(*r1kh
));
1776 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1777 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1778 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1779 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1780 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1783 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1786 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1793 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1795 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1799 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1801 struct ft_remote_r0kh
*r0kh
;
1802 struct ft_remote_r1kh
*r1kh
;
1804 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1806 if (wpa_auth
->conf
.r0kh_list
)
1807 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1810 for (; r0kh
; r0kh
= r0kh
->next
) {
1813 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1818 if (wpa_auth
->conf
.r1kh_list
)
1819 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1822 for (; r1kh
; r1kh
= r1kh
->next
) {
1825 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1832 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1834 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1835 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1837 if (wpa_auth
->conf
.r0kh_list
)
1838 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1842 r0kh_next
= r0kh
->next
;
1843 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1846 r0kh_prev
->next
= r0kh_next
;
1848 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1856 if (wpa_auth
->conf
.r1kh_list
)
1857 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1861 r1kh_next
= r1kh
->next
;
1862 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1865 r1kh_prev
->next
= r1kh_next
;
1867 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1877 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1879 wpa_ft_deinit_seq(wpa_auth
);
1880 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1884 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1885 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1887 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1889 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1892 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1893 &r0kh
, &r0kh_wildcard
);
1895 if (!r0kh_wildcard
) {
1896 /* r0kh removed after neg_timeout and might need re-adding */
1900 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1901 f_r0kh_id
, f_r0kh_id_len
);
1904 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1905 wpa_auth
->conf
.rkh_neg_timeout
);
1906 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1908 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1910 wpa_auth
->conf
.rkh_neg_timeout
);
1914 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1916 struct wpa_state_machine
*sm
= eloop_ctx
;
1918 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1920 if (sm
->ft_pending_pull_left_retries
<= 0)
1921 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1923 /* cancel multiple timeouts */
1924 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1929 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1930 const u8
*ies
, size_t ies_len
,
1931 const u8
*pmk_r0_name
)
1933 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1935 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1936 size_t packet_len
, key_len
;
1937 struct ft_rrb_seq f_seq
;
1938 int tsecs
, tusecs
, first
;
1939 struct wpabuf
*ft_pending_req_ies
;
1941 struct tlv_list req_enc
[] = {
1942 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1943 .data
= pmk_r0_name
},
1944 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1946 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1948 struct tlv_list req_auth
[] = {
1949 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1950 .data
= sm
->ft_pending_pull_nonce
},
1951 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1952 .data
= (u8
*) &f_seq
},
1953 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1954 .data
= sm
->r0kh_id
},
1955 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1956 .data
= f_r1kh_id
},
1957 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1960 if (sm
->ft_pending_pull_left_retries
<= 0)
1962 first
= sm
->ft_pending_pull_left_retries
==
1963 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1964 sm
->ft_pending_pull_left_retries
--;
1966 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1967 &r0kh
, &r0kh_wildcard
);
1969 /* Keep r0kh sufficiently long in the list for seq num check */
1970 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1971 1 + ftRRBseqTimeout
;
1973 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1974 } else if (r0kh_wildcard
) {
1975 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1976 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1977 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1978 r0kh_wildcard
->addr
,
1979 sm
->r0kh_id
, sm
->r0kh_id_len
,
1983 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1984 sm
->r0kh_id
, sm
->r0kh_id_len
);
1987 if (is_zero_ether_addr(r0kh
->addr
)) {
1988 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1989 sm
->r0kh_id
, sm
->r0kh_id_len
);
1992 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1993 wpa_printf(MSG_DEBUG
,
1994 "FT: R0KH-ID points to self - no matching key available");
1999 key_len
= sizeof(r0kh
->key
);
2001 if (r0kh
->seq
->rx
.num_last
== 0) {
2002 /* A sequence request will be sent out anyway when pull
2003 * response is received. Send it out now to avoid one RTT. */
2004 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
2005 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
2006 key_len
, NULL
, 0, NULL
, 0, NULL
);
2009 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request from " MACSTR
2010 " to remote R0KH address " MACSTR
,
2011 MAC2STR(sm
->wpa_auth
->addr
), MAC2STR(r0kh
->addr
));
2014 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
2015 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2020 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
2021 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
2025 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
2026 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
2027 &packet
, &packet_len
) < 0)
2030 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
2031 wpabuf_free(sm
->ft_pending_req_ies
);
2032 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
2033 if (!sm
->ft_pending_req_ies
) {
2038 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
2039 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
2040 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
2042 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
2043 packet
, packet_len
);
2051 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
2052 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
2054 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2055 struct vlan_description vlan
;
2056 const u8
*identity
, *radius_cui
;
2057 size_t identity_len
, radius_cui_len
;
2058 int session_timeout
;
2059 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2060 SHA384_MAC_LEN
: PMK_LEN
;
2062 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2063 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2068 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2069 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2071 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2073 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2074 pmk_r0_name
, sm
->pairwise
, &vlan
, expires_in
,
2075 session_timeout
, identity
, identity_len
,
2076 radius_cui
, radius_cui_len
);
2080 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, struct wpa_ptk
*ptk
)
2082 u8 pmk_r0
[PMK_LEN_MAX
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2083 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2084 SHA384_MAC_LEN
: PMK_LEN
;
2085 size_t pmk_r1_len
= pmk_r0_len
;
2086 u8 pmk_r1
[PMK_LEN_MAX
];
2087 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2088 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
2089 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
2090 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
2091 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
2092 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
2093 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
2094 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
2095 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2096 struct vlan_description vlan
;
2097 const u8
*identity
, *radius_cui
;
2098 size_t identity_len
, radius_cui_len
;
2099 int session_timeout
;
2103 if (sm
->xxkey_len
> 0) {
2105 mpmk_len
= sm
->xxkey_len
;
2106 } else if (sm
->pmksa
) {
2107 mpmk
= sm
->pmksa
->pmk
;
2108 mpmk_len
= sm
->pmksa
->pmk_len
;
2110 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
2115 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2116 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2121 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2122 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2124 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2126 if (wpa_derive_pmk_r0(mpmk
, mpmk_len
, ssid
, ssid_len
, mdid
,
2127 r0kh
, r0kh_len
, sm
->addr
,
2128 pmk_r0
, pmk_r0_name
,
2129 wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
)) < 0)
2131 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, pmk_r0_len
);
2132 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
2133 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2134 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2136 sm
->pairwise
, &vlan
, expires_in
,
2137 session_timeout
, identity
, identity_len
,
2138 radius_cui
, radius_cui_len
);
2140 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
, r1kh
, sm
->addr
,
2141 pmk_r1
, sm
->pmk_r1_name
) < 0)
2143 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, pmk_r1_len
);
2144 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
2146 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2147 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
, pmk_r1_len
,
2148 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
2149 expires_in
, session_timeout
, identity
,
2150 identity_len
, radius_cui
, radius_cui_len
);
2152 return wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2153 sm
->addr
, sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
2154 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
2158 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
2159 const u8
*addr
, int idx
, u8
*seq
)
2161 if (wpa_auth
->cb
->get_seqnum
== NULL
)
2163 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
2167 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2170 struct wpa_group
*gsm
= sm
->group
;
2171 size_t subelem_len
, pad_len
;
2178 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2180 kek_len
= sm
->PTK
.kek2_len
;
2183 kek_len
= sm
->PTK
.kek_len
;
2186 key_len
= gsm
->GTK_len
;
2187 if (key_len
> sizeof(keybuf
))
2191 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2194 pad_len
= key_len
% 8;
2196 pad_len
= 8 - pad_len
;
2197 if (key_len
+ pad_len
< 16)
2199 if (pad_len
&& key_len
< sizeof(keybuf
)) {
2200 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
2201 os_memset(keybuf
+ key_len
, 0, pad_len
);
2202 keybuf
[key_len
] = 0xdd;
2206 key
= gsm
->GTK
[gsm
->GN
- 1];
2209 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
2212 subelem_len
= 13 + key_len
+ 8;
2213 subelem
= os_zalloc(subelem_len
);
2214 if (subelem
== NULL
)
2217 subelem
[0] = FTIE_SUBELEM_GTK
;
2218 subelem
[1] = 11 + key_len
+ 8;
2219 /* Key ID in B0-B1 of Key Info */
2220 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
2221 subelem
[4] = gsm
->GTK_len
;
2222 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
2223 if (aes_wrap(kek
, kek_len
, key_len
/ 8, key
, subelem
+ 13)) {
2224 wpa_printf(MSG_DEBUG
,
2225 "FT: GTK subelem encryption failed: kek_len=%d",
2231 forced_memzero(keybuf
, sizeof(keybuf
));
2237 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2240 struct wpa_group
*gsm
= sm
->group
;
2246 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2248 kek_len
= sm
->PTK
.kek2_len
;
2251 kek_len
= sm
->PTK
.kek_len
;
2254 igtk_len
= wpa_cipher_key_len(sm
->wpa_auth
->conf
.group_mgmt_cipher
);
2256 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2258 subelem_len
= 1 + 1 + 2 + 6 + 1 + igtk_len
+ 8;
2259 subelem
= os_zalloc(subelem_len
);
2260 if (subelem
== NULL
)
2264 *pos
++ = FTIE_SUBELEM_IGTK
;
2265 *pos
++ = subelem_len
- 2;
2266 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
2268 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
2271 if (aes_wrap(kek
, kek_len
, igtk_len
/ 8,
2272 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
2273 wpa_printf(MSG_DEBUG
,
2274 "FT: IGTK subelem encryption failed: kek_len=%d",
2285 static u8
* wpa_ft_bigtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2288 struct wpa_group
*gsm
= sm
->group
;
2294 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2296 kek_len
= sm
->PTK
.kek2_len
;
2299 kek_len
= sm
->PTK
.kek_len
;
2302 bigtk_len
= wpa_cipher_key_len(sm
->wpa_auth
->conf
.group_mgmt_cipher
);
2304 /* Sub-elem ID[1] | Length[1] | KeyID[2] | BIPN[6] | Key Length[1] |
2306 subelem_len
= 1 + 1 + 2 + 6 + 1 + bigtk_len
+ 8;
2307 subelem
= os_zalloc(subelem_len
);
2308 if (subelem
== NULL
)
2312 *pos
++ = FTIE_SUBELEM_BIGTK
;
2313 *pos
++ = subelem_len
- 2;
2314 WPA_PUT_LE16(pos
, gsm
->GN_bigtk
);
2316 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_bigtk
, pos
);
2319 if (aes_wrap(kek
, kek_len
, bigtk_len
/ 8,
2320 gsm
->IGTK
[gsm
->GN_bigtk
- 6], pos
)) {
2321 wpa_printf(MSG_DEBUG
,
2322 "FT: BIGTK subelem encryption failed: kek_len=%d",
2333 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
2334 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
2335 const u8
*ies
, size_t ies_len
)
2337 struct ieee802_11_elems parse
;
2338 struct rsn_rdie
*rdie
;
2340 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
2342 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
2345 if (end
- pos
< (int) sizeof(*rdie
)) {
2346 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
2350 *pos
++ = WLAN_EID_RIC_DATA
;
2351 *pos
++ = sizeof(*rdie
);
2352 rdie
= (struct rsn_rdie
*) pos
;
2354 rdie
->descr_count
= 0;
2355 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2356 pos
+= sizeof(*rdie
);
2358 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2360 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2362 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2366 if (parse
.wmm_tspec
) {
2367 struct wmm_tspec_element
*tspec
;
2369 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2370 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2371 "(%d)", (int) parse
.wmm_tspec_len
);
2373 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2376 if (end
- pos
< (int) sizeof(*tspec
)) {
2377 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2380 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2383 tspec
= (struct wmm_tspec_element
*) pos
;
2384 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2388 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2391 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2392 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2393 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2395 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2396 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2398 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2400 /* TSPEC accepted; include updated TSPEC in response */
2401 rdie
->descr_count
= 1;
2402 pos
+= sizeof(struct wmm_tspec_element
);
2406 #endif /* NEED_AP_MLME */
2408 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2411 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2412 sizeof(struct wmm_tspec_element
));
2415 rdie
->status_code
= host_to_le16(res
);
2417 /* TSPEC accepted; include updated TSPEC in
2419 rdie
->descr_count
= 1;
2420 pos
+= sizeof(struct wmm_tspec_element
);
2426 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2427 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2432 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2433 const u8
*ric
, size_t ric_len
)
2435 const u8
*rpos
, *start
;
2436 const struct rsn_rdie
*rdie
;
2438 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2441 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2442 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2443 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2445 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2446 rpos
+= 2 + rpos
[1];
2449 while (rpos
+ 2 <= ric
+ ric_len
&&
2450 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2451 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2453 rpos
+= 2 + rpos
[1];
2455 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2457 start
, rpos
- start
);
2464 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2465 size_t max_len
, int auth_alg
,
2466 const u8
*req_ies
, size_t req_ies_len
,
2469 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2470 u8
*fte_mic
, *elem_count
;
2471 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2472 u8 rsnxe_buf
[10], *rsnxe
= rsnxe_buf
;
2476 struct wpa_auth_config
*conf
;
2477 struct wpa_ft_ies parse
;
2479 u8
*anonce
, *snonce
;
2487 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
2488 conf
= &sm
->wpa_auth
->conf
;
2490 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2493 end
= pos
+ max_len
;
2495 #ifdef CONFIG_TESTING_OPTIONS
2496 if (auth_alg
== WLAN_AUTH_FT
&&
2497 sm
->wpa_auth
->conf
.rsne_override_ft_set
) {
2498 wpa_printf(MSG_DEBUG
,
2499 "TESTING: RSNE FT override for MIC calculation");
2500 rsnie
= sm
->wpa_auth
->conf
.rsne_override_ft
;
2501 rsnie_len
= sm
->wpa_auth
->conf
.rsne_override_ft_len
;
2502 if (end
- pos
< (long int) rsnie_len
)
2504 os_memcpy(pos
, rsnie
, rsnie_len
);
2507 if (rsnie_len
> PMKID_LEN
&& sm
->pmk_r1_name_valid
) {
2510 /* Replace all 0xff PMKID with the valid PMKR1Name */
2511 for (idx
= 0; idx
< PMKID_LEN
; idx
++) {
2512 if (rsnie
[rsnie_len
- 1 - idx
] != 0xff)
2515 if (idx
== PMKID_LEN
)
2516 os_memcpy(&rsnie
[rsnie_len
- PMKID_LEN
],
2517 sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
);
2520 #endif /* CONFIG_TESTING_OPTIONS */
2521 if (auth_alg
== WLAN_AUTH_FT
||
2522 ((auth_alg
== WLAN_AUTH_FILS_SK
||
2523 auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
2524 auth_alg
== WLAN_AUTH_FILS_PK
) &&
2525 (sm
->wpa_key_mgmt
& (WPA_KEY_MGMT_FT_FILS_SHA256
|
2526 WPA_KEY_MGMT_FT_FILS_SHA384
)))) {
2527 if (!sm
->pmk_r1_name_valid
) {
2528 wpa_printf(MSG_ERROR
,
2529 "FT: PMKR1Name is not valid for Assoc Resp RSNE");
2532 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name for Assoc Resp RSNE",
2533 sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
);
2535 * RSN (only present if this is a Reassociation Response and
2536 * part of a fast BSS transition; or if this is a
2537 * (Re)Association Response frame during an FT initial mobility
2538 * domain association using FILS)
2540 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2548 /* Mobility Domain Information */
2549 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2556 /* Fast BSS Transition Information */
2557 if (auth_alg
== WLAN_AUTH_FT
) {
2558 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2560 wpa_printf(MSG_DEBUG
,
2561 "FT: Failed to add GTK subelement");
2564 r0kh_id
= sm
->r0kh_id
;
2565 r0kh_id_len
= sm
->r0kh_id_len
;
2566 anonce
= sm
->ANonce
;
2567 snonce
= sm
->SNonce
;
2568 if (sm
->mgmt_frame_prot
) {
2572 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2574 wpa_printf(MSG_DEBUG
,
2575 "FT: Failed to add IGTK subelement");
2579 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2586 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2587 subelem_len
+= igtk_len
;
2590 if (sm
->mgmt_frame_prot
&& conf
->beacon_prot
) {
2595 bigtk
= wpa_ft_bigtk_subelem(sm
, &bigtk_len
);
2597 wpa_printf(MSG_DEBUG
,
2598 "FT: Failed to add BIGTK subelement");
2602 nbuf
= os_realloc(subelem
, subelem_len
+ bigtk_len
);
2609 os_memcpy(subelem
+ subelem_len
, bigtk
, bigtk_len
);
2610 subelem_len
+= bigtk_len
;
2614 if (wpa_auth_uses_ocv(sm
)) {
2615 struct wpa_channel_info ci
;
2618 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
2619 wpa_printf(MSG_WARNING
,
2620 "Failed to get channel info for OCI element");
2625 subelem_len
+= 2 + OCV_OCI_LEN
;
2626 nbuf
= os_realloc(subelem
, subelem_len
);
2633 ocipos
= subelem
+ subelem_len
- 2 - OCV_OCI_LEN
;
2634 *ocipos
++ = FTIE_SUBELEM_OCI
;
2635 *ocipos
++ = OCV_OCI_LEN
;
2636 if (ocv_insert_oci(&ci
, &ocipos
) < 0) {
2641 #endif /* CONFIG_OCV */
2643 r0kh_id
= conf
->r0_key_holder
;
2644 r0kh_id_len
= conf
->r0_key_holder_len
;
2648 rsnxe_used
= (auth_alg
== WLAN_AUTH_FT
) &&
2649 (conf
->sae_pwe
== 1 || conf
->sae_pwe
== 2);
2650 res
= wpa_write_ftie(conf
, use_sha384
, r0kh_id
, r0kh_id_len
,
2651 anonce
, snonce
, pos
, end
- pos
,
2652 subelem
, subelem_len
, rsnxe_used
);
2661 struct rsn_ftie_sha384
*_ftie
=
2662 (struct rsn_ftie_sha384
*) (ftie
+ 2);
2664 fte_mic
= _ftie
->mic
;
2665 elem_count
= &_ftie
->mic_control
[1];
2667 struct rsn_ftie
*_ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2669 fte_mic
= _ftie
->mic
;
2670 elem_count
= &_ftie
->mic_control
[1];
2672 if (auth_alg
== WLAN_AUTH_FT
)
2673 *elem_count
= 3; /* Information element count */
2676 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
, use_sha384
) == 0
2678 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2680 if (auth_alg
== WLAN_AUTH_FT
)
2682 ieee802_11_ie_count(ric_start
,
2685 if (ric_start
== pos
)
2691 res
= wpa_write_rsnxe(&sm
->wpa_auth
->conf
, rsnxe
,
2697 #ifdef CONFIG_TESTING_OPTIONS
2698 if (auth_alg
== WLAN_AUTH_FT
&&
2699 sm
->wpa_auth
->conf
.rsnxe_override_ft_set
) {
2700 wpa_printf(MSG_DEBUG
,
2701 "TESTING: RSNXE FT override for MIC calculation");
2702 rsnxe
= sm
->wpa_auth
->conf
.rsnxe_override_ft
;
2703 rsnxe_len
= sm
->wpa_auth
->conf
.rsnxe_override_ft_len
;
2705 #endif /* CONFIG_TESTING_OPTIONS */
2706 if (auth_alg
== WLAN_AUTH_FT
&& rsnxe_len
)
2709 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2711 kck_len
= sm
->PTK
.kck2_len
;
2714 kck_len
= sm
->PTK
.kck_len
;
2716 if (auth_alg
== WLAN_AUTH_FT
&&
2717 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2718 mdie
, mdie_len
, ftie
, ftie_len
,
2720 ric_start
, ric_start
? pos
- ric_start
: 0,
2721 rsnxe_len
? rsnxe
: NULL
, rsnxe_len
,
2723 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2727 os_free(sm
->assoc_resp_ftie
);
2728 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2729 if (!sm
->assoc_resp_ftie
)
2731 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2737 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2739 enum wpa_alg alg
, const u8
*addr
, int idx
,
2740 u8
*key
, size_t key_len
,
2741 enum key_flag key_flag
)
2743 if (wpa_auth
->cb
->set_key
== NULL
)
2745 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2746 key
, key_len
, key_flag
);
2750 static inline int wpa_auth_add_sta_ft(struct wpa_authenticator
*wpa_auth
,
2753 if (!wpa_auth
->cb
->add_sta_ft
)
2755 return wpa_auth
->cb
->add_sta_ft(wpa_auth
->cb_ctx
, addr
);
2759 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
, int retry
)
2764 /* MLME-SETKEYS.request(PTK) */
2765 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2766 klen
= wpa_cipher_key_len(sm
->pairwise
);
2767 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2768 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2769 "PTK configuration", sm
->pairwise
);
2773 if (sm
->tk_already_set
) {
2774 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2775 * PN in the driver */
2776 wpa_printf(MSG_DEBUG
,
2777 "FT: Do not re-install same PTK to the driver");
2782 wpa_auth_add_sta_ft(sm
->wpa_auth
, sm
->addr
);
2784 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2785 * most likely without this.. At the moment, STA entry is added only
2786 * after association has been completed. This function will be called
2787 * again after association to get the PTK configured, but that could be
2788 * optimized by adding the STA entry earlier.
2790 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, sm
->keyidx_active
,
2791 sm
->PTK
.tk
, klen
, KEY_FLAG_PAIRWISE_RX_TX
))
2794 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2795 sm
->pairwise_set
= TRUE
;
2796 sm
->tk_already_set
= TRUE
;
2800 /* Derive PMK-R1 from PSK, check all available PSK */
2801 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2802 const u8
*req_pmk_r1_name
,
2803 u8
*out_pmk_r1
, int *out_pairwise
,
2804 struct vlan_description
*out_vlan
,
2805 const u8
**out_identity
, size_t *out_identity_len
,
2806 const u8
**out_radius_cui
,
2807 size_t *out_radius_cui_len
,
2808 int *out_session_timeout
)
2810 const u8
*pmk
= NULL
;
2811 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2812 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2813 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2814 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2815 const u8
*r0kh
= sm
->r0kh_id
;
2816 size_t r0kh_len
= sm
->r0kh_id_len
;
2817 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2818 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2819 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2822 pairwise
= sm
->pairwise
;
2825 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2830 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2832 pmk_r0
, pmk_r0_name
, 0) < 0 ||
2833 wpa_derive_pmk_r1(pmk_r0
, PMK_LEN
, pmk_r0_name
, r1kh
,
2834 sm
->addr
, pmk_r1
, pmk_r1_name
) < 0 ||
2835 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2836 WPA_PMK_NAME_LEN
) != 0)
2839 /* We found a PSK that matches the requested pmk_r1_name */
2840 wpa_printf(MSG_DEBUG
,
2841 "FT: Found PSK to generate PMK-R1 locally");
2842 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2844 *out_pairwise
= pairwise
;
2845 os_memcpy(sm
->PMK
, pmk
, PMK_LEN
);
2846 sm
->pmk_len
= PMK_LEN
;
2848 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2849 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2850 MACSTR
, MAC2STR(sm
->addr
));
2854 if (out_identity
&& out_identity_len
) {
2855 *out_identity_len
= wpa_ft_get_identity(
2856 sm
->wpa_auth
, sm
->addr
, out_identity
);
2859 if (out_radius_cui
&& out_radius_cui_len
) {
2860 *out_radius_cui_len
= wpa_ft_get_radius_cui(
2861 sm
->wpa_auth
, sm
->addr
, out_radius_cui
);
2864 if (out_session_timeout
) {
2865 *out_session_timeout
= wpa_ft_get_session_timeout(
2866 sm
->wpa_auth
, sm
->addr
);
2872 wpa_printf(MSG_DEBUG
,
2873 "FT: Did not find PSK to generate PMK-R1 locally");
2878 /* Detect the configuration the station asked for.
2879 * Required to detect FT-PSK and pairwise cipher.
2881 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2882 struct wpa_ft_ies
*parse
)
2884 int key_mgmt
, ciphers
;
2886 if (sm
->wpa_key_mgmt
)
2889 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2891 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2892 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2895 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2896 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2897 #ifdef CONFIG_SHA384
2898 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X_SHA384
)
2899 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X_SHA384
;
2900 #endif /* CONFIG_SHA384 */
2901 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2902 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2904 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2905 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2906 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2907 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2908 #endif /* CONFIG_FILS */
2909 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2911 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2913 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2916 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2922 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2923 struct wpa_state_machine
*sm
,
2924 const u8
*r0kh_id
, size_t r0kh_id_len
,
2925 const u8
*req_pmk_r0_name
,
2926 const u8
*req_pmk_r1_name
,
2927 u8
*out_pmk_r1
, int *out_pairwise
,
2928 struct vlan_description
*vlan
,
2929 const u8
**identity
, size_t *identity_len
,
2930 const u8
**radius_cui
,
2931 size_t *radius_cui_len
,
2932 int *out_session_timeout
)
2934 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2935 const struct wpa_ft_pmk_r0_sa
*r0
;
2936 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2938 int session_timeout
= 0;
2939 struct os_reltime now
;
2941 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2942 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2944 return -1; /* not our R0KH-ID */
2946 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2947 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2949 return -1; /* no matching PMKR0Name in local cache */
2951 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2953 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_len
, r0
->pmk_r0_name
,
2954 conf
->r1_key_holder
,
2955 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2957 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, r0
->pmk_r0_len
);
2958 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2960 os_get_reltime(&now
);
2962 expires_in
= r0
->expiration
- now
.sec
;
2964 if (r0
->session_timeout
)
2965 session_timeout
= r0
->session_timeout
- now
.sec
;
2967 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, r0
->pmk_r0_len
,
2969 sm
->pairwise
, r0
->vlan
, expires_in
, session_timeout
,
2970 r0
->identity
, r0
->identity_len
,
2971 r0
->radius_cui
, r0
->radius_cui_len
);
2973 *out_pairwise
= sm
->pairwise
;
2978 os_memset(vlan
, 0, sizeof(*vlan
));
2981 if (identity
&& identity_len
) {
2982 *identity
= r0
->identity
;
2983 *identity_len
= r0
->identity_len
;
2986 if (radius_cui
&& radius_cui_len
) {
2987 *radius_cui
= r0
->radius_cui
;
2988 *radius_cui_len
= r0
->radius_cui_len
;
2991 *out_session_timeout
= session_timeout
;
2997 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2998 const u8
*ies
, size_t ies_len
,
2999 u8
**resp_ies
, size_t *resp_ies_len
)
3001 struct rsn_mdie
*mdie
;
3002 u8 pmk_r1
[PMK_LEN_MAX
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
3003 u8 ptk_name
[WPA_PMK_NAME_LEN
];
3004 struct wpa_auth_config
*conf
;
3005 struct wpa_ft_ies parse
;
3009 int pairwise
, session_timeout
= 0;
3010 struct vlan_description vlan
;
3011 const u8
*identity
, *radius_cui
;
3012 size_t identity_len
= 0, radius_cui_len
= 0;
3019 sm
->pmk_r1_name_valid
= 0;
3020 conf
= &sm
->wpa_auth
->conf
;
3022 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
3025 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, -1)) {
3026 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
3027 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3029 use_sha384
= wpa_key_mgmt_sha384(parse
.key_mgmt
);
3030 pmk_r1_len
= use_sha384
? SHA384_MAC_LEN
: PMK_LEN
;
3032 mdie
= (struct rsn_mdie
*) parse
.mdie
;
3033 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
3034 os_memcmp(mdie
->mobility_domain
,
3035 sm
->wpa_auth
->conf
.mobility_domain
,
3036 MOBILITY_DOMAIN_ID_LEN
) != 0) {
3037 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
3038 return WLAN_STATUS_INVALID_MDIE
;
3042 struct rsn_ftie_sha384
*ftie
;
3044 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
3045 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
3046 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3047 return WLAN_STATUS_INVALID_FTIE
;
3050 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
3052 struct rsn_ftie
*ftie
;
3054 ftie
= (struct rsn_ftie
*) parse
.ftie
;
3055 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
3056 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3057 return WLAN_STATUS_INVALID_FTIE
;
3060 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
3063 if (parse
.r0kh_id
== NULL
) {
3064 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
3065 return WLAN_STATUS_INVALID_FTIE
;
3068 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
3069 parse
.r0kh_id
, parse
.r0kh_id_len
);
3070 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
3071 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
3073 if (parse
.rsn_pmkid
== NULL
) {
3074 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
3075 return WLAN_STATUS_INVALID_PMKID
;
3078 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
3079 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3081 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
3082 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
3083 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
3084 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
3085 pmk_r1_name
, use_sha384
) < 0)
3086 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3087 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
3088 pmk_r1_name
, WPA_PMK_NAME_LEN
);
3090 if (conf
->ft_psk_generate_local
&&
3091 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
3092 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
3093 &vlan
, &identity
, &identity_len
,
3094 &radius_cui
, &radius_cui_len
,
3095 &session_timeout
) < 0)
3096 return WLAN_STATUS_INVALID_PMKID
;
3097 wpa_printf(MSG_DEBUG
,
3098 "FT: Generated PMK-R1 for FT-PSK locally");
3099 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
3100 pmk_r1
, &pmk_r1_len
, &pairwise
, &vlan
,
3101 &identity
, &identity_len
, &radius_cui
,
3102 &radius_cui_len
, &session_timeout
) < 0) {
3103 wpa_printf(MSG_DEBUG
,
3104 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
3105 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
3106 parse
.r0kh_id
, parse
.r0kh_id_len
,
3108 pmk_r1_name
, pmk_r1
, &pairwise
,
3109 &vlan
, &identity
, &identity_len
,
3110 &radius_cui
, &radius_cui_len
,
3111 &session_timeout
) == 0) {
3112 wpa_printf(MSG_DEBUG
,
3113 "FT: Generated PMK-R1 based on local PMK-R0");
3114 goto pmk_r1_derived
;
3117 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
3118 wpa_printf(MSG_DEBUG
,
3119 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
3120 return WLAN_STATUS_INVALID_PMKID
;
3123 return -1; /* Status pending */
3125 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
3129 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, pmk_r1_len
);
3130 sm
->pmk_r1_name_valid
= 1;
3131 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
3132 os_memcpy(sm
->pmk_r1
, pmk_r1
, pmk_r1_len
);
3133 sm
->pmk_r1_len
= pmk_r1_len
;
3135 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
3136 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
3138 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3141 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
3142 sm
->SNonce
, WPA_NONCE_LEN
);
3143 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
3144 sm
->ANonce
, WPA_NONCE_LEN
);
3146 if (wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
3147 sm
->addr
, sm
->wpa_auth
->addr
, pmk_r1_name
,
3148 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
3150 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3152 sm
->pairwise
= pairwise
;
3153 sm
->PTK_valid
= TRUE
;
3154 sm
->tk_already_set
= FALSE
;
3155 wpa_ft_install_ptk(sm
, 0);
3157 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
3158 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
3159 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3161 if (wpa_ft_set_identity(sm
->wpa_auth
, sm
->addr
,
3162 identity
, identity_len
) < 0 ||
3163 wpa_ft_set_radius_cui(sm
->wpa_auth
, sm
->addr
,
3164 radius_cui
, radius_cui_len
) < 0) {
3165 wpa_printf(MSG_DEBUG
, "FT: Failed to configure identity/CUI");
3166 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3168 wpa_ft_set_session_timeout(sm
->wpa_auth
, sm
->addr
, session_timeout
);
3170 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
3171 2 + FT_R1KH_ID_LEN
+ 200;
3172 *resp_ies
= os_zalloc(buflen
);
3173 if (*resp_ies
== NULL
)
3177 end
= *resp_ies
+ buflen
;
3179 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
3184 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
3189 ret
= wpa_write_ftie(conf
, use_sha384
, parse
.r0kh_id
, parse
.r0kh_id_len
,
3190 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0,
3196 *resp_ies_len
= pos
- *resp_ies
;
3198 return WLAN_STATUS_SUCCESS
;
3202 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3206 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
3207 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
3208 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
3209 u16 auth_transaction
, u16 status
,
3210 const u8
*ies
, size_t ies_len
),
3215 size_t resp_ies_len
;
3219 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
3220 "WPA SM not available");
3224 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
3225 " BSSID=" MACSTR
" transaction=%d",
3226 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
3227 sm
->ft_pending_cb
= cb
;
3228 sm
->ft_pending_cb_ctx
= ctx
;
3229 sm
->ft_pending_auth_transaction
= auth_transaction
;
3230 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3231 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
3234 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
3239 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
3240 " auth_transaction=%d status=%u (%s)",
3241 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
,
3242 status2str(status
));
3243 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3244 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
3245 resp_ies
, resp_ies_len
);
3250 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
3253 struct wpa_ft_ies parse
;
3254 struct rsn_mdie
*mdie
;
3255 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
3256 size_t mic_len
= 16;
3261 const u8
*anonce
, *snonce
, *fte_mic
;
3264 struct wpa_auth_config
*conf
;
3267 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3269 conf
= &sm
->wpa_auth
->conf
;
3270 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
3272 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
3274 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, use_sha384
) < 0) {
3275 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
3276 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3279 if (parse
.rsn
== NULL
) {
3280 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
3281 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3284 if (parse
.rsn_pmkid
== NULL
) {
3285 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
3286 return WLAN_STATUS_INVALID_PMKID
;
3289 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
3291 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
3292 "with the PMKR1Name derived from auth request");
3293 return WLAN_STATUS_INVALID_PMKID
;
3296 mdie
= (struct rsn_mdie
*) parse
.mdie
;
3297 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
3298 os_memcmp(mdie
->mobility_domain
, conf
->mobility_domain
,
3299 MOBILITY_DOMAIN_ID_LEN
) != 0) {
3300 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
3301 return WLAN_STATUS_INVALID_MDIE
;
3305 struct rsn_ftie_sha384
*ftie
;
3307 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
3308 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3309 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3310 return WLAN_STATUS_INVALID_FTIE
;
3313 anonce
= ftie
->anonce
;
3314 snonce
= ftie
->snonce
;
3315 rsnxe_used
= ftie
->mic_control
[0] & 0x01;
3316 fte_elem_count
= ftie
->mic_control
[1];
3317 fte_mic
= ftie
->mic
;
3319 struct rsn_ftie
*ftie
;
3321 ftie
= (struct rsn_ftie
*) parse
.ftie
;
3322 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3323 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3324 return WLAN_STATUS_INVALID_FTIE
;
3327 anonce
= ftie
->anonce
;
3328 snonce
= ftie
->snonce
;
3329 rsnxe_used
= ftie
->mic_control
[0] & 0x01;
3330 fte_elem_count
= ftie
->mic_control
[1];
3331 fte_mic
= ftie
->mic
;
3334 if (os_memcmp(snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
3335 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
3336 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
3337 snonce
, WPA_NONCE_LEN
);
3338 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
3339 sm
->SNonce
, WPA_NONCE_LEN
);
3340 return WLAN_STATUS_INVALID_FTIE
;
3343 if (os_memcmp(anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
3344 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
3345 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
3346 anonce
, WPA_NONCE_LEN
);
3347 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
3348 sm
->ANonce
, WPA_NONCE_LEN
);
3349 return WLAN_STATUS_INVALID_FTIE
;
3353 if (parse
.r0kh_id
== NULL
) {
3354 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
3355 return WLAN_STATUS_INVALID_FTIE
;
3358 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
3359 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
3361 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
3362 "the current R0KH-ID");
3363 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
3364 parse
.r0kh_id
, parse
.r0kh_id_len
);
3365 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
3366 sm
->r0kh_id
, sm
->r0kh_id_len
);
3367 return WLAN_STATUS_INVALID_FTIE
;
3370 if (parse
.r1kh_id
== NULL
) {
3371 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
3372 return WLAN_STATUS_INVALID_FTIE
;
3375 if (os_memcmp_const(parse
.r1kh_id
, conf
->r1_key_holder
,
3376 FT_R1KH_ID_LEN
) != 0) {
3377 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
3379 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
3380 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
3381 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
3382 conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
3383 return WLAN_STATUS_INVALID_FTIE
;
3386 if (parse
.rsn_pmkid
== NULL
||
3387 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
3389 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
3390 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
3391 return WLAN_STATUS_INVALID_PMKID
;
3396 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
3399 if (fte_elem_count
!= count
) {
3400 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
3401 "Control: received %u expected %u",
3402 fte_elem_count
, count
);
3403 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3406 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
3408 kck_len
= sm
->PTK
.kck2_len
;
3411 kck_len
= sm
->PTK
.kck_len
;
3413 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
3414 parse
.mdie
- 2, parse
.mdie_len
+ 2,
3415 parse
.ftie
- 2, parse
.ftie_len
+ 2,
3416 parse
.rsn
- 2, parse
.rsn_len
+ 2,
3417 parse
.ric
, parse
.ric_len
,
3418 parse
.rsnxe
? parse
.rsnxe
- 2 : NULL
,
3419 parse
.rsnxe
? parse
.rsnxe_len
+ 2 : 0,
3421 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
3422 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3425 if (os_memcmp_const(mic
, fte_mic
, mic_len
) != 0) {
3426 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
3427 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
3428 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
3429 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
3431 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
3432 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
3433 parse
.mdie
- 2, parse
.mdie_len
+ 2);
3434 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
3435 parse
.ftie
- 2, parse
.ftie_len
+ 2);
3436 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
3437 parse
.rsn
- 2, parse
.rsn_len
+ 2);
3438 wpa_hexdump(MSG_MSGDUMP
, "FT: RSNXE",
3439 parse
.rsnxe
? parse
.rsnxe
- 2 : NULL
,
3440 parse
.rsnxe
? parse
.rsnxe_len
+ 2 : 0);
3441 return WLAN_STATUS_INVALID_FTIE
;
3444 if (rsnxe_used
&& (conf
->sae_pwe
== 1 || conf
->sae_pwe
== 2) &&
3446 wpa_printf(MSG_INFO
,
3447 "FT: FTE indicated that STA uses RSNXE, but RSNXE was not included");
3448 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3452 if (wpa_auth_uses_ocv(sm
)) {
3453 struct wpa_channel_info ci
;
3457 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
3458 wpa_printf(MSG_WARNING
,
3459 "Failed to get channel info to validate received OCI in (Re)Assoc Request");
3460 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3463 if (get_sta_tx_parameters(sm
,
3464 channel_width_to_int(ci
.chanwidth
),
3465 ci
.seg1_idx
, &tx_chanwidth
,
3467 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3469 if (ocv_verify_tx_params(parse
.oci
, parse
.oci_len
, &ci
,
3470 tx_chanwidth
, tx_seg1_idx
) != 0) {
3471 wpa_printf(MSG_WARNING
, "%s", ocv_errorstr
);
3472 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3475 #endif /* CONFIG_OCV */
3477 return WLAN_STATUS_SUCCESS
;
3481 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
3483 const u8
*sta_addr
, *target_ap
;
3487 struct ft_rrb_frame
*frame
;
3493 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3494 * FT Request action frame body[variable]
3498 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
3499 "(len=%lu)", (unsigned long) len
);
3504 sta_addr
= data
+ 2;
3505 target_ap
= data
+ 8;
3509 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
3510 " Target AP=" MACSTR
" Action=%d)",
3511 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
3513 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
3514 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
3515 "STA=" MACSTR
" STA-Address=" MACSTR
,
3516 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
3521 * Do some sanity checking on the target AP address (not own and not
3522 * broadcast. This could be extended to filter based on a list of known
3523 * APs in the MD (if such a list were configured).
3525 if ((target_ap
[0] & 0x01) ||
3526 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
3527 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
3532 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
3534 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
3535 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
3539 /* RRB - Forward action frame to the target AP */
3540 frame
= os_malloc(sizeof(*frame
) + len
);
3543 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3544 frame
->packet_type
= FT_PACKET_REQUEST
;
3545 frame
->action_length
= host_to_le16(len
);
3546 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
3547 os_memcpy(frame
+ 1, data
, len
);
3549 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
3550 sizeof(*frame
) + len
);
3557 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
3558 u16 auth_transaction
, u16 resp
,
3559 const u8
*ies
, size_t ies_len
)
3561 struct wpa_state_machine
*sm
= ctx
;
3562 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
3564 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
3565 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
3569 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
3570 const u8
*current_ap
, const u8
*sta_addr
,
3571 const u8
*body
, size_t len
)
3573 struct wpa_state_machine
*sm
;
3576 size_t resp_ies_len
;
3579 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
3581 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
3586 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
3588 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
3589 sm
->ft_pending_cb_ctx
= sm
;
3590 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
3591 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3592 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
3595 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
3600 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
3601 resp_ies
, resp_ies_len
);
3607 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
3608 const u8
*current_ap
, const u8
*sta_addr
,
3609 u16 status
, const u8
*resp_ies
,
3610 size_t resp_ies_len
)
3612 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
3614 struct ft_rrb_frame
*frame
;
3617 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
3618 " CurrentAP=" MACSTR
" status=%u (%s)",
3619 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
,
3620 status2str(status
));
3621 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3623 /* RRB - Forward action frame response to the Current AP */
3626 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3627 * Status_Code[2] FT Request action frame body[variable]
3629 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
3631 frame
= os_malloc(sizeof(*frame
) + rlen
);
3634 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3635 frame
->packet_type
= FT_PACKET_RESPONSE
;
3636 frame
->action_length
= host_to_le16(rlen
);
3637 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
3638 pos
= (u8
*) (frame
+ 1);
3639 *pos
++ = WLAN_ACTION_FT
;
3640 *pos
++ = 2; /* Action: Response */
3641 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
3643 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
3645 WPA_PUT_LE16(pos
, status
);
3648 os_memcpy(pos
, resp_ies
, resp_ies_len
);
3650 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
3651 sizeof(*frame
) + rlen
);
3658 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
3659 const struct tlv_list
*tlvs
,
3660 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3661 const u8
*r1kh_id
, const u8
*s1kh_id
,
3662 const struct tlv_list
*tlv_auth
,
3663 const u8
*src_addr
, u8 type
,
3664 u8
**packet
, size_t *packet_len
)
3666 u8 pmk_r1
[PMK_LEN_MAX
];
3667 size_t pmk_r1_len
= pmk_r0
->pmk_r0_len
;
3668 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3669 u8 f_pairwise
[sizeof(le16
)];
3670 u8 f_expires_in
[sizeof(le16
)];
3671 u8 f_session_timeout
[sizeof(le32
)];
3673 int session_timeout
;
3674 struct os_reltime now
;
3676 struct tlv_list sess_tlv
[] = {
3677 { .type
= FT_RRB_PMK_R1
, .len
= pmk_r1_len
,
3679 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3680 .data
= pmk_r1_name
},
3681 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3682 .data
= f_pairwise
},
3683 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3684 .data
= f_expires_in
},
3685 { .type
= FT_RRB_IDENTITY
, .len
= pmk_r0
->identity_len
,
3686 .data
= pmk_r0
->identity
},
3687 { .type
= FT_RRB_RADIUS_CUI
, .len
= pmk_r0
->radius_cui_len
,
3688 .data
= pmk_r0
->radius_cui
},
3689 { .type
= FT_RRB_SESSION_TIMEOUT
,
3690 .len
= sizeof(f_session_timeout
),
3691 .data
= f_session_timeout
},
3692 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3695 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_len
,
3696 pmk_r0
->pmk_r0_name
, r1kh_id
,
3697 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3699 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1 (for peer AP)",
3700 pmk_r1
, pmk_r1_len
);
3701 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name (for peer AP)",
3702 pmk_r1_name
, WPA_PMK_NAME_LEN
);
3703 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3705 os_get_reltime(&now
);
3706 if (pmk_r0
->expiration
> now
.sec
)
3707 expires_in
= pmk_r0
->expiration
- now
.sec
;
3708 else if (pmk_r0
->expiration
)
3712 WPA_PUT_LE16(f_expires_in
, expires_in
);
3714 if (pmk_r0
->session_timeout
> now
.sec
)
3715 session_timeout
= pmk_r0
->session_timeout
- now
.sec
;
3716 else if (pmk_r0
->session_timeout
)
3717 session_timeout
= 1;
3719 session_timeout
= 0;
3720 WPA_PUT_LE32(f_session_timeout
, session_timeout
);
3722 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3723 pmk_r0
->vlan
, src_addr
, type
,
3724 packet
, packet_len
);
3726 forced_memzero(pmk_r1
, sizeof(pmk_r1
));
3732 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3734 const u8
*enc
, size_t enc_len
,
3735 const u8
*auth
, size_t auth_len
,
3738 const char *msgtype
= "pull request";
3739 u8
*plain
= NULL
, *packet
= NULL
;
3740 size_t plain_len
= 0, packet_len
= 0;
3741 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3745 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3746 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3747 size_t f_pmk_r0_name_len
;
3748 const struct wpa_ft_pmk_r0_sa
*r0
;
3750 struct tlv_list resp
[2];
3751 struct tlv_list resp_auth
[5];
3752 struct ft_rrb_seq f_seq
;
3754 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3756 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3757 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3759 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3760 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3764 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3765 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3767 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3770 key_len
= sizeof(r1kh
->key
);
3771 } else if (r1kh_wildcard
) {
3772 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3773 key
= r1kh_wildcard
->key
;
3774 key_len
= sizeof(r1kh_wildcard
->key
);
3779 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3780 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3782 seq_ret
= FT_RRB_SEQ_DROP
;
3784 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3785 auth
, auth_len
, msgtype
, no_defer
);
3786 if (!no_defer
&& r1kh_wildcard
&&
3787 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3788 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3789 seq_ret
= FT_RRB_SEQ_DEFER
;
3792 if (seq_ret
== FT_RRB_SEQ_DROP
)
3795 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3796 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3797 &plain
, &plain_len
) < 0)
3801 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3803 wpa_auth
->conf
.rkh_pos_timeout
);
3807 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3808 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3809 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3810 enc
, enc_len
, auth
, auth_len
,
3811 &wpa_ft_rrb_rx_pull
);
3815 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3817 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3818 wpa_auth
->conf
.rkh_pos_timeout
);
3820 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3821 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3824 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3825 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3827 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3828 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3832 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull response from " MACSTR
3834 MAC2STR(wpa_auth
->addr
), MAC2STR(src_addr
));
3836 resp
[0].type
= FT_RRB_S1KH_ID
;
3837 resp
[0].len
= f_s1kh_id_len
;
3838 resp
[0].data
= f_s1kh_id
;
3839 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3841 resp
[1].data
= NULL
;
3843 resp_auth
[0].type
= FT_RRB_NONCE
;
3844 resp_auth
[0].len
= f_nonce_len
;
3845 resp_auth
[0].data
= f_nonce
;
3846 resp_auth
[1].type
= FT_RRB_SEQ
;
3847 resp_auth
[1].len
= sizeof(f_seq
);
3848 resp_auth
[1].data
= (u8
*) &f_seq
;
3849 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3850 resp_auth
[2].len
= f_r0kh_id_len
;
3851 resp_auth
[2].data
= f_r0kh_id
;
3852 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3853 resp_auth
[3].len
= f_r1kh_id_len
;
3854 resp_auth
[3].data
= f_r1kh_id
;
3855 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3856 resp_auth
[4].len
= 0;
3857 resp_auth
[4].data
= NULL
;
3859 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0) {
3860 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3861 ret
= wpa_ft_rrb_build(key
, key_len
, resp
, NULL
, resp_auth
,
3862 NULL
, wpa_auth
->addr
,
3863 FT_PACKET_R0KH_R1KH_RESP
,
3864 &packet
, &packet_len
);
3866 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
,
3867 f_s1kh_id
, resp_auth
, wpa_auth
->addr
,
3868 FT_PACKET_R0KH_R1KH_RESP
,
3869 &packet
, &packet_len
);
3873 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3874 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3885 /* @returns 0 on success
3887 * -2 if FR_RRB_PAIRWISE is missing
3889 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3890 const u8
*src_addr
, u8 type
,
3891 const u8
*enc
, size_t enc_len
,
3892 const u8
*auth
, size_t auth_len
,
3893 const char *msgtype
, u8
*s1kh_id_out
,
3894 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3896 const u8
*enc
, size_t enc_len
,
3897 const u8
*auth
, size_t auth_len
,
3901 size_t plain_len
= 0;
3902 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3906 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3907 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3908 const u8
*f_expires_in
;
3909 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3910 const u8
*f_identity
, *f_radius_cui
;
3911 const u8
*f_session_timeout
;
3912 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3913 size_t f_expires_in_len
;
3914 size_t f_identity_len
, f_radius_cui_len
;
3915 size_t f_session_timeout_len
;
3919 int session_timeout
;
3920 struct vlan_description vlan
;
3923 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3924 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3926 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3927 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3929 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3930 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3934 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3938 key_len
= sizeof(r0kh
->key
);
3939 } else if (r0kh_wildcard
) {
3940 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3941 key
= r0kh_wildcard
->key
;
3942 key_len
= sizeof(r0kh_wildcard
->key
);
3947 seq_ret
= FT_RRB_SEQ_DROP
;
3949 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3950 auth
, auth_len
, msgtype
,
3953 if (cb
&& r0kh_wildcard
&&
3954 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3955 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3956 seq_ret
= FT_RRB_SEQ_DEFER
;
3959 if (seq_ret
== FT_RRB_SEQ_DROP
)
3962 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3963 src_addr
, type
, &plain
, &plain_len
) < 0)
3967 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3968 f_r0kh_id
, f_r0kh_id_len
,
3969 wpa_auth
->conf
.rkh_pos_timeout
);
3973 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3974 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3975 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3976 enc
, enc_len
, auth
, auth_len
, cb
);
3980 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3982 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3983 wpa_auth
->conf
.rkh_pos_timeout
);
3985 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3986 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3989 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3992 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3993 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3996 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3997 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3998 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
4000 pmk_r1_len
= PMK_LEN
;
4001 if (wpa_ft_rrb_get_tlv(plain
, plain_len
, FT_RRB_PMK_R1
, &f_pmk_r1_len
,
4003 (f_pmk_r1_len
== PMK_LEN
|| f_pmk_r1_len
== SHA384_MAC_LEN
))
4004 pmk_r1_len
= f_pmk_r1_len
;
4005 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, pmk_r1_len
);
4006 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, pmk_r1_len
);
4008 pairwise
= WPA_GET_LE16(f_pairwise
);
4010 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
4013 expires_in
= WPA_GET_LE16(f_expires_in
);
4017 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
4020 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
4021 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
4022 wpa_ft_rrb_dump(plain
, plain_len
);
4026 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
4027 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
4029 RRB_GET_OPTIONAL(FT_RRB_IDENTITY
, identity
, msgtype
, -1);
4031 wpa_hexdump_ascii(MSG_DEBUG
, "FT: Identity", f_identity
,
4034 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI
, radius_cui
, msgtype
, -1);
4036 wpa_hexdump_ascii(MSG_DEBUG
, "FT: CUI", f_radius_cui
,
4039 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT
, session_timeout
, msgtype
,
4041 if (f_session_timeout
)
4042 session_timeout
= WPA_GET_LE32(f_session_timeout
);
4044 session_timeout
= 0;
4045 wpa_printf(MSG_DEBUG
, "FT: session_timeout %d", session_timeout
);
4047 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, pmk_r1_len
,
4049 pairwise
, &vlan
, expires_in
, session_timeout
,
4050 f_identity
, f_identity_len
, f_radius_cui
,
4051 f_radius_cui_len
) < 0)
4056 bin_clear_free(plain
, plain_len
);
4063 static void ft_finish_pull(struct wpa_state_machine
*sm
)
4067 size_t resp_ies_len
;
4070 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
4073 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
4074 wpabuf_len(sm
->ft_pending_req_ies
),
4075 &resp_ies
, &resp_ies_len
);
4077 /* this loop is broken by ft_pending_pull_left_retries */
4078 wpa_printf(MSG_DEBUG
,
4079 "FT: Callback postponed until response is available");
4082 wpabuf_free(sm
->ft_pending_req_ies
);
4083 sm
->ft_pending_req_ies
= NULL
;
4085 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
4086 " - status %u", MAC2STR(sm
->addr
), status
);
4088 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
4089 sm
->ft_pending_auth_transaction
+ 1, status
,
4090 resp_ies
, resp_ies_len
);
4095 struct ft_get_sta_ctx
{
4098 struct wpa_state_machine
*sm
;
4102 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
4104 struct ft_get_sta_ctx
*info
= ctx
;
4106 if ((info
->s1kh_id
&&
4107 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
4108 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
4109 FT_RRB_NONCE_LEN
) != 0 ||
4110 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
4119 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
4121 const u8
*enc
, size_t enc_len
,
4122 const u8
*auth
, size_t auth_len
,
4125 const char *msgtype
= "pull response";
4127 struct ft_get_sta_ctx ctx
;
4128 u8 s1kh_id
[ETH_ALEN
];
4132 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
4134 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
4135 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
4137 os_memset(&ctx
, 0, sizeof(ctx
));
4138 ctx
.nonce
= f_nonce
;
4139 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
4140 /* nonce not found */
4141 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
4145 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
4146 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
4147 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
4157 ctx
.s1kh_id
= s1kh_id
;
4158 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
4159 wpa_printf(MSG_DEBUG
,
4160 "FT: Response to a pending pull request for " MACSTR
,
4161 MAC2STR(ctx
.sm
->addr
));
4162 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
4164 ctx
.sm
->ft_pending_pull_left_retries
= 0;
4165 ft_finish_pull(ctx
.sm
);
4173 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
4175 const u8
*enc
, size_t enc_len
,
4176 const u8
*auth
, size_t auth_len
, int no_defer
)
4178 const char *msgtype
= "push";
4180 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
4182 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4183 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
4184 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
4191 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
4192 const u8
*src_addr
, int type
,
4193 const u8
*enc
, size_t enc_len
,
4194 const u8
*auth
, size_t auth_len
,
4195 struct ft_remote_seq
**rkh_seq
,
4196 u8
**key
, size_t *key_len
,
4197 struct ft_remote_r0kh
**r0kh_out
,
4198 struct ft_remote_r1kh
**r1kh_out
,
4199 struct ft_remote_r0kh
**r0kh_wildcard_out
,
4200 struct ft_remote_r1kh
**r1kh_wildcard_out
)
4202 struct ft_remote_r0kh
*r0kh
= NULL
;
4203 struct ft_remote_r1kh
*r1kh
= NULL
;
4204 const u8
*f_r0kh_id
, *f_r1kh_id
;
4205 size_t f_r0kh_id_len
, f_r1kh_id_len
;
4206 int to_r0kh
, to_r1kh
;
4208 size_t plain_len
= 0;
4209 struct ft_remote_r0kh
*r0kh_wildcard
;
4210 struct ft_remote_r1kh
*r1kh_wildcard
;
4212 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4213 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4215 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
4216 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
4218 if (to_r0kh
&& to_r1kh
) {
4219 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
4223 if (!to_r0kh
&& !to_r1kh
) {
4224 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
4229 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
4230 &r0kh
, &r0kh_wildcard
);
4231 if (!r0kh_wildcard
&&
4232 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4233 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
4234 f_r0kh_id
, f_r0kh_id_len
);
4239 *key_len
= sizeof(r0kh
->key
);
4241 *key
= r0kh_wildcard
->key
;
4242 *key_len
= sizeof(r0kh_wildcard
->key
);
4247 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
4249 if (!r1kh_wildcard
&&
4250 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4251 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
4252 f_r1kh_id
, FT_R1KH_ID_LEN
);
4257 *key_len
= sizeof(r1kh
->key
);
4259 *key
= r1kh_wildcard
->key
;
4260 *key_len
= sizeof(r1kh_wildcard
->key
);
4264 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
4265 src_addr
, type
, &plain
, &plain_len
) < 0)
4272 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
4273 src_addr
, f_r0kh_id
,
4279 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
4280 *rkh_seq
= r0kh
->seq
;
4283 if (r0kh_wildcard_out
)
4284 *r0kh_wildcard_out
= r0kh_wildcard
;
4289 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
4290 src_addr
, f_r1kh_id
,
4295 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
4296 *rkh_seq
= r1kh
->seq
;
4299 if (r1kh_wildcard_out
)
4300 *r1kh_wildcard_out
= r1kh_wildcard
;
4309 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
4311 const u8
*enc
, size_t enc_len
,
4312 const u8
*auth
, size_t auth_len
,
4316 struct ft_rrb_seq f_seq
;
4317 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
4318 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
4319 struct ft_remote_seq
*rkh_seq
= NULL
;
4320 u8
*packet
= NULL
, *key
= NULL
;
4321 size_t packet_len
= 0, key_len
= 0;
4322 struct tlv_list seq_resp_auth
[5];
4324 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
4326 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
4327 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4328 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
4331 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
4332 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
4334 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4335 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4337 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
4338 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4342 wpa_printf(MSG_DEBUG
, "FT: Send sequence number response from " MACSTR
4344 MAC2STR(wpa_auth
->addr
), MAC2STR(src_addr
));
4346 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
4347 seq_resp_auth
[0].len
= f_nonce_len
;
4348 seq_resp_auth
[0].data
= f_nonce
;
4349 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
4350 seq_resp_auth
[1].len
= sizeof(f_seq
);
4351 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
4352 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
4353 seq_resp_auth
[2].len
= f_r0kh_id_len
;
4354 seq_resp_auth
[2].data
= f_r0kh_id
;
4355 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
4356 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
4357 seq_resp_auth
[3].data
= f_r1kh_id
;
4358 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
4359 seq_resp_auth
[4].len
= 0;
4360 seq_resp_auth
[4].data
= NULL
;
4362 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
4363 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4364 &packet
, &packet_len
) < 0)
4367 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
4368 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
4378 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
4380 const u8
*enc
, size_t enc_len
,
4381 const u8
*auth
, size_t auth_len
,
4386 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
4387 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
4388 const u8
*f_nonce
, *f_seq
;
4389 size_t f_nonce_len
, f_seq_len
;
4390 struct ft_remote_seq
*rkh_seq
= NULL
;
4391 struct ft_remote_item
*item
;
4392 struct os_reltime now
, now_remote
;
4394 const struct ft_rrb_seq
*msg_both
;
4395 u32 msg_dom
, msg_seq
;
4397 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
4399 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4400 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4401 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
4402 &r1kh_wildcard
) < 0)
4405 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
4406 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
4410 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
4412 if (os_memcmp_const(f_nonce
, item
->nonce
,
4413 FT_RRB_NONCE_LEN
) != 0 ||
4414 os_get_reltime(&now
) < 0 ||
4415 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
4422 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
4427 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
4428 wpa_auth
->conf
.rkh_pos_timeout
);
4430 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
4434 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
4435 wpa_auth
->conf
.rkh_pos_timeout
);
4437 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
4440 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
4441 auth_len
, "seq response", 1);
4442 if (seq_ret
== FT_RRB_SEQ_OK
) {
4443 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
4444 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
4445 auth_len
, "seq response");
4447 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
4449 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
4451 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
4453 msg_dom
= le_to_host32(msg_both
->dom
);
4454 msg_seq
= le_to_host32(msg_both
->seq
);
4455 now_remote
.sec
= le_to_host32(msg_both
->ts
);
4456 now_remote
.usec
= 0;
4458 rkh_seq
->rx
.num_last
= 2;
4459 rkh_seq
->rx
.dom
= msg_dom
;
4460 rkh_seq
->rx
.offsetidx
= 0;
4461 /* Accept some older, possibly cached packets as well */
4462 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
4463 dl_list_len(&rkh_seq
->rx
.queue
);
4464 rkh_seq
->rx
.last
[1] = msg_seq
;
4466 /* local time - offset = remote time
4467 * <=> local time - remote time = offset */
4468 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
4471 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
4479 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4480 const u8
*data
, size_t data_len
)
4482 struct ft_rrb_frame
*frame
;
4484 const u8
*pos
, *end
, *start
;
4486 const u8
*sta_addr
, *target_ap_addr
;
4488 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
4491 if (data_len
< sizeof(*frame
)) {
4492 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
4493 (unsigned long) data_len
);
4498 frame
= (struct ft_rrb_frame
*) pos
;
4499 pos
+= sizeof(*frame
);
4501 alen
= le_to_host16(frame
->action_length
);
4502 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
4503 "action_length=%d ap_address=" MACSTR
,
4504 frame
->frame_type
, frame
->packet_type
, alen
,
4505 MAC2STR(frame
->ap_address
));
4507 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
4508 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
4509 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
4510 "unrecognized type %d", frame
->frame_type
);
4514 if (alen
> data_len
- sizeof(*frame
)) {
4515 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
4520 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
4522 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
4523 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
4524 "room for Action Frame body); alen=%lu",
4525 (unsigned long) alen
);
4531 if (*pos
!= WLAN_ACTION_FT
) {
4532 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
4541 target_ap_addr
= pos
;
4543 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
4544 MACSTR
" target_ap_addr=" MACSTR
,
4545 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
4547 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
4548 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
4551 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
4552 "RRB Request", action
);
4556 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
4557 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
4558 "RRB Request does not match with own "
4563 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
4564 sta_addr
, pos
, end
- pos
) < 0)
4566 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
4569 if (end
- pos
< 2) {
4570 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
4571 "code in RRB Response");
4574 status_code
= WPA_GET_LE16(pos
);
4576 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
4577 "(status_code=%d)", status_code
);
4579 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
4582 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
4583 "packet_type %d", frame
->packet_type
);
4591 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4592 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
4595 const u8
*auth
, *enc
;
4599 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI(" MACSTR
4600 ") received frame from remote AP "
4601 MACSTR
" oui_suffix=%u dst=" MACSTR
,
4602 MAC2STR(wpa_auth
->addr
), MAC2STR(src_addr
), oui_suffix
,
4604 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB frame payload", data
, data_len
);
4606 if (is_multicast_ether_addr(src_addr
)) {
4607 wpa_printf(MSG_DEBUG
,
4608 "FT: RRB-OUI received frame from multicast address "
4609 MACSTR
, MAC2STR(src_addr
));
4613 if (is_multicast_ether_addr(dst_addr
))
4616 if (data_len
< sizeof(u16
)) {
4617 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4621 alen
= WPA_GET_LE16(data
);
4622 if (data_len
< sizeof(u16
) + alen
) {
4623 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4627 auth
= data
+ sizeof(u16
);
4628 wpa_hexdump(MSG_MSGDUMP
, "FT: Authenticated payload", auth
, alen
);
4629 enc
= data
+ sizeof(u16
) + alen
;
4630 elen
= data_len
- sizeof(u16
) - alen
;
4631 wpa_hexdump(MSG_MSGDUMP
, "FT: Encrypted payload", enc
, elen
);
4633 switch (oui_suffix
) {
4634 case FT_PACKET_R0KH_R1KH_PULL
:
4635 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4638 case FT_PACKET_R0KH_R1KH_RESP
:
4639 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4642 case FT_PACKET_R0KH_R1KH_PUSH
:
4643 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4646 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
4647 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4650 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
4651 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
4658 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
4659 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
4660 struct ft_remote_r1kh
*r1kh
,
4665 struct ft_rrb_seq f_seq
;
4666 struct tlv_list push
[] = {
4667 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
4669 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
4670 .data
= pmk_r0
->pmk_r0_name
},
4671 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4673 struct tlv_list push_auth
[] = {
4674 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
4675 .data
= (u8
*) &f_seq
},
4676 { .type
= FT_RRB_R0KH_ID
,
4677 .len
= wpa_auth
->conf
.r0_key_holder_len
,
4678 .data
= wpa_auth
->conf
.r0_key_holder
},
4679 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
4681 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4684 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
4685 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4689 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 push from " MACSTR
4690 " to remote R0KH address " MACSTR
,
4691 MAC2STR(wpa_auth
->addr
), MAC2STR(r1kh
->addr
));
4693 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
4694 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
4695 FT_PACKET_R0KH_R1KH_PUSH
,
4696 &packet
, &packet_len
) < 0)
4699 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4700 packet
, packet_len
);
4707 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
4709 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
4710 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
4711 struct ft_remote_r1kh
*r1kh
;
4713 if (!wpa_auth
->conf
.pmk_r1_push
)
4715 if (!wpa_auth
->conf
.r1kh_list
)
4718 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
4719 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4726 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4728 r0
->pmk_r1_pushed
= 1;
4730 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4731 "for STA " MACSTR
, MAC2STR(addr
));
4733 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4734 if (is_zero_ether_addr(r1kh
->addr
) ||
4735 is_zero_ether_addr(r1kh
->id
))
4737 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4739 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4743 #endif /* CONFIG_IEEE80211R_AP */