2 * hostapd - IEEE 802.11r - Fast BSS Transition
3 * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "utils/list.h"
14 #include "common/ieee802_11_defs.h"
15 #include "common/ieee802_11_common.h"
16 #include "common/ocv.h"
17 #include "drivers/driver.h"
18 #include "crypto/aes.h"
19 #include "crypto/aes_siv.h"
20 #include "crypto/aes_wrap.h"
21 #include "crypto/sha384.h"
22 #include "crypto/random.h"
23 #include "ap_config.h"
24 #include "ieee802_11.h"
27 #include "wpa_auth_i.h"
30 #ifdef CONFIG_IEEE80211R_AP
32 const unsigned int ftRRBseqTimeout
= 10;
33 const unsigned int ftRRBmaxQueueLen
= 100;
36 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
37 const u8
*current_ap
, const u8
*sta_addr
,
38 u16 status
, const u8
*resp_ies
,
40 static void ft_finish_pull(struct wpa_state_machine
*sm
);
41 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
42 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
52 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
53 * @key: AES-SIV key for AEAD
54 * @key_len: Length of key in octets
55 * @enc: Pointer to encrypted TLVs
56 * @enc_len: Length of encrypted TLVs in octets
57 * @auth: Pointer to authenticated TLVs
58 * @auth_len: Length of authenticated TLVs in octets
59 * @src_addr: MAC address of the frame sender
60 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
61 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
62 * needs to be freed by the caller if not NULL;
63 * will only be returned on success
64 * @plain_len: Pointer to return the length of the allocated plaintext buffer
66 * Returns: 0 on success, -1 on error
68 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
69 const u8
*enc
, size_t enc_len
,
70 const u8
*auth
, const size_t auth_len
,
71 const u8
*src_addr
, u8 type
,
72 u8
**plain
, size_t *plain_size
)
74 const u8
*ad
[3] = { src_addr
, auth
, &type
};
75 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
77 wpa_printf(MSG_DEBUG
, "FT(RRB): src_addr=" MACSTR
" type=%u",
78 MAC2STR(src_addr
), type
);
79 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
80 wpa_hexdump(MSG_DEBUG
, "FT(RRB): encrypted TLVs", enc
, enc_len
);
81 wpa_hexdump(MSG_DEBUG
, "FT(RRB): authenticated TLVs", auth
, auth_len
);
83 if (!key
) { /* skip decryption */
84 *plain
= os_memdup(enc
, enc_len
);
85 if (enc_len
> 0 && !*plain
)
88 *plain_size
= enc_len
;
96 if (enc_len
< AES_BLOCK_SIZE
)
99 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
103 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
105 if (enc_len
< AES_BLOCK_SIZE
+ 2)
108 /* Try to work around Ethernet devices that add extra
109 * two octet padding even if the frame is longer than
110 * the minimum Ethernet frame. */
112 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
117 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
118 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
119 *plain
, *plain_size
);
126 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
132 /* get first tlv record in packet matching type
133 * @data (decrypted) packet
134 * @return 0 on success else -1
136 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
137 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
139 const struct ft_rrb_tlv
*f
;
145 type16
= host_to_le16(type
);
147 while (left
>= sizeof(*f
)) {
148 f
= (const struct ft_rrb_tlv
*) plain
;
152 len
= le_to_host16(f
->len
);
155 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
159 if (f
->type
== type16
) {
173 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
175 const struct ft_rrb_tlv
*f
;
181 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
182 while (left
>= sizeof(*f
)) {
183 f
= (const struct ft_rrb_tlv
*) plain
;
187 len
= le_to_host16(f
->len
);
189 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
190 le_to_host16(f
->type
), len
);
193 wpa_printf(MSG_DEBUG
,
194 "FT: RRB message truncated: left %zu bytes, need %zu",
199 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
206 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
208 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
212 static int cmp_int(const void *a
, const void *b
)
222 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
223 struct vlan_description
*vlan
)
225 struct ft_rrb_tlv
*f
;
234 os_memset(vlan
, 0, sizeof(*vlan
));
236 while (left
>= sizeof(*f
)) {
237 f
= (struct ft_rrb_tlv
*) plain
;
242 len
= le_to_host16(f
->len
);
243 type
= le_to_host16(f
->type
);
246 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
250 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
253 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
254 wpa_printf(MSG_DEBUG
,
255 "FT: RRB VLAN_UNTAGGED invalid length");
259 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
260 wpa_printf(MSG_DEBUG
,
261 "FT: RRB VLAN_TAGGED invalid length");
265 while (len
>= sizeof(le16
)) {
266 vlan_id
= WPA_GET_LE16(plain
);
267 plain
+= sizeof(le16
);
268 left
-= sizeof(le16
);
271 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
272 wpa_printf(MSG_DEBUG
,
273 "FT: RRB VLAN ID invalid %d",
278 if (type
== FT_RRB_VLAN_UNTAGGED
)
279 vlan
->untagged
= vlan_id
;
281 if (type
== FT_RRB_VLAN_TAGGED
&&
282 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
283 vlan
->tagged
[taggedidx
] = vlan_id
;
285 } else if (type
== FT_RRB_VLAN_TAGGED
) {
286 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
296 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
298 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
304 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
312 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
313 tlv_len
+= sizeof(struct ft_rrb_tlv
);
314 tlv_len
+= tlvs
[i
].len
;
321 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
326 struct ft_rrb_tlv
*hdr
;
334 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
335 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
337 tlv_len
+= sizeof(*hdr
);
338 hdr
= (struct ft_rrb_tlv
*) pos
;
339 hdr
->type
= host_to_le16(tlvs
[i
].type
);
340 hdr
->len
= host_to_le16(tlvs
[i
].len
);
341 pos
= start
+ tlv_len
;
343 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
345 if (tlvs
[i
].len
== 0)
347 tlv_len
+= tlvs
[i
].len
;
348 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
349 pos
= start
+ tlv_len
;
356 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
361 if (!vlan
|| !vlan
->notempty
)
364 if (vlan
->untagged
) {
365 tlv_len
+= sizeof(struct ft_rrb_tlv
);
366 tlv_len
+= sizeof(le16
);
369 tlv_len
+= sizeof(struct ft_rrb_tlv
);
370 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
371 tlv_len
+= sizeof(le16
);
377 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
378 u8
*start
, u8
*endpos
)
382 struct ft_rrb_tlv
*hdr
;
385 if (!vlan
|| !vlan
->notempty
)
389 if (vlan
->untagged
) {
390 tlv_len
+= sizeof(*hdr
);
391 if (start
+ tlv_len
> endpos
)
393 hdr
= (struct ft_rrb_tlv
*) pos
;
394 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
395 hdr
->len
= host_to_le16(sizeof(le16
));
396 pos
= start
+ tlv_len
;
398 tlv_len
+= sizeof(le16
);
399 if (start
+ tlv_len
> endpos
)
401 WPA_PUT_LE16(pos
, vlan
->untagged
);
402 pos
= start
+ tlv_len
;
405 if (!vlan
->tagged
[0])
408 tlv_len
+= sizeof(*hdr
);
409 if (start
+ tlv_len
> endpos
)
411 hdr
= (struct ft_rrb_tlv
*) pos
;
412 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
413 len
= 0; /* len is computed below */
414 pos
= start
+ tlv_len
;
416 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
417 tlv_len
+= sizeof(le16
);
418 if (start
+ tlv_len
> endpos
)
421 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
422 pos
= start
+ tlv_len
;
425 hdr
->len
= host_to_le16(len
);
431 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
432 const struct tlv_list
*tlvs2
,
433 const struct vlan_description
*vlan
,
434 u8
**plain
, size_t *plain_len
)
439 tlv_len
= wpa_ft_tlv_len(tlvs1
);
440 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
441 tlv_len
+= wpa_ft_vlan_len(vlan
);
443 *plain_len
= tlv_len
;
444 *plain
= os_zalloc(tlv_len
);
446 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
451 endpos
= *plain
+ tlv_len
;
452 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
453 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
454 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
458 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
472 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
473 const u8
*plain
, const size_t plain_len
,
474 const u8
*auth
, const size_t auth_len
,
475 const u8
*src_addr
, u8 type
, u8
*enc
)
477 const u8
*ad
[3] = { src_addr
, auth
, &type
};
478 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
480 wpa_printf(MSG_DEBUG
, "FT(RRB): src_addr=" MACSTR
" type=%u",
481 MAC2STR(src_addr
), type
);
482 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
484 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
485 wpa_hexdump(MSG_DEBUG
, "FT(RRB): authenticated TLVs", auth
, auth_len
);
488 /* encryption not needed, return plaintext as packet */
489 os_memcpy(enc
, plain
, plain_len
);
490 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
491 3, ad
, ad_len
, enc
) < 0) {
492 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
495 wpa_hexdump(MSG_DEBUG
, "FT(RRB): encrypted TLVs",
496 enc
, plain_len
+ AES_BLOCK_SIZE
);
503 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
504 * @key: AES-SIV key for AEAD
505 * @key_len: Length of key in octets
506 * @tlvs_enc0: First set of to-be-encrypted TLVs
507 * @tlvs_enc1: Second set of to-be-encrypted TLVs
508 * @tlvs_auth: Set of to-be-authenticated TLVs
509 * @src_addr: MAC address of the frame sender
510 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
511 * @packet Pointer to return the pointer to the allocated packet buffer;
512 * needs to be freed by the caller if not null;
513 * will only be returned on success
514 * @packet_len: Pointer to return the length of the allocated buffer in octets
515 * Returns: 0 on success, -1 on error
517 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
518 const struct tlv_list
*tlvs_enc0
,
519 const struct tlv_list
*tlvs_enc1
,
520 const struct tlv_list
*tlvs_auth
,
521 const struct vlan_description
*vlan
,
522 const u8
*src_addr
, u8 type
,
523 u8
**packet
, size_t *packet_len
)
525 u8
*plain
= NULL
, *auth
= NULL
, *pos
, *tmp
;
526 size_t plain_len
= 0, auth_len
= 0;
531 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
534 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
537 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
539 *packet_len
+= AES_BLOCK_SIZE
;
540 #define RRB_MIN_MSG_LEN 64
541 if (*packet_len
< RRB_MIN_MSG_LEN
) {
542 pad_len
= RRB_MIN_MSG_LEN
- *packet_len
;
543 if (pad_len
< sizeof(struct ft_rrb_tlv
))
544 pad_len
= sizeof(struct ft_rrb_tlv
);
545 wpa_printf(MSG_DEBUG
,
546 "FT: Pad message to minimum Ethernet frame length (%d --> %d)",
547 (int) *packet_len
, (int) (*packet_len
+ pad_len
));
548 *packet_len
+= pad_len
;
549 tmp
= os_realloc(auth
, auth_len
+ pad_len
);
553 pos
= auth
+ auth_len
;
554 WPA_PUT_LE16(pos
, FT_RRB_LAST_EMPTY
);
556 WPA_PUT_LE16(pos
, pad_len
- sizeof(struct ft_rrb_tlv
));
558 os_memset(pos
, 0, pad_len
- sizeof(struct ft_rrb_tlv
));
562 *packet
= os_zalloc(*packet_len
);
567 WPA_PUT_LE16(pos
, auth_len
);
569 os_memcpy(pos
, auth
, auth_len
);
571 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
572 auth_len
, src_addr
, type
, pos
) < 0)
574 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB frame payload", *packet
, *packet_len
);
579 bin_clear_free(plain
, plain_len
);
583 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
593 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
594 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
595 &f_##field##_len, &f_##field) < 0 || \
596 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
597 wpa_printf(MSG_INFO, "FT: Missing required " #field \
598 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
599 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
604 #define RRB_GET(type, field, txt, checklength) \
605 RRB_GET_SRC(plain, type, field, txt, checklength)
606 #define RRB_GET_AUTH(type, field, txt, checklength) \
607 RRB_GET_SRC(auth, type, field, txt, checklength)
609 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
610 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
611 &f_##field##_len, &f_##field) < 0 || \
612 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
613 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
614 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
615 f_##field##_len = 0; \
620 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
621 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
622 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
623 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
625 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
626 const u8
*data
, size_t data_len
)
628 if (wpa_auth
->cb
->send_ether
== NULL
)
630 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
631 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
636 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
637 const u8
*dst
, u8 oui_suffix
,
638 const u8
*data
, size_t data_len
)
640 if (!wpa_auth
->cb
->send_oui
)
642 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
" (len=%u)",
643 oui_suffix
, MAC2STR(dst
), (unsigned int) data_len
);
644 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
649 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
650 const u8
*dst
, const u8
*data
, size_t data_len
)
652 if (wpa_auth
->cb
->send_ft_action
== NULL
)
654 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
659 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
660 const u8
*addr
, const u8
*p2p_dev_addr
,
663 if (wpa_auth
->cb
->get_psk
== NULL
)
665 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
666 prev_psk
, NULL
, NULL
);
670 static struct wpa_state_machine
*
671 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
673 if (wpa_auth
->cb
->add_sta
== NULL
)
675 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
679 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
680 const u8
*sta_addr
, struct vlan_description
*vlan
)
682 if (!wpa_auth
->cb
->set_vlan
)
684 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
688 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
689 const u8
*sta_addr
, struct vlan_description
*vlan
)
691 if (!wpa_auth
->cb
->get_vlan
)
693 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
698 wpa_ft_set_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
699 const u8
*identity
, size_t identity_len
)
701 if (!wpa_auth
->cb
->set_identity
)
703 return wpa_auth
->cb
->set_identity(wpa_auth
->cb_ctx
, sta_addr
, identity
,
709 wpa_ft_get_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
713 if (!wpa_auth
->cb
->get_identity
)
715 return wpa_auth
->cb
->get_identity(wpa_auth
->cb_ctx
, sta_addr
, buf
);
720 wpa_ft_set_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
721 const u8
*radius_cui
, size_t radius_cui_len
)
723 if (!wpa_auth
->cb
->set_radius_cui
)
725 return wpa_auth
->cb
->set_radius_cui(wpa_auth
->cb_ctx
, sta_addr
,
726 radius_cui
, radius_cui_len
);
731 wpa_ft_get_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
735 if (!wpa_auth
->cb
->get_radius_cui
)
737 return wpa_auth
->cb
->get_radius_cui(wpa_auth
->cb_ctx
, sta_addr
, buf
);
742 wpa_ft_set_session_timeout(struct wpa_authenticator
*wpa_auth
,
743 const u8
*sta_addr
, int session_timeout
)
745 if (!wpa_auth
->cb
->set_session_timeout
)
747 wpa_auth
->cb
->set_session_timeout(wpa_auth
->cb_ctx
, sta_addr
,
753 wpa_ft_get_session_timeout(struct wpa_authenticator
*wpa_auth
,
756 if (!wpa_auth
->cb
->get_session_timeout
)
758 return wpa_auth
->cb
->get_session_timeout(wpa_auth
->cb_ctx
, sta_addr
);
762 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
764 u8
*tspec_ie
, size_t tspec_ielen
)
766 if (wpa_auth
->cb
->add_tspec
== NULL
) {
767 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
770 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
776 static int wpa_channel_info(struct wpa_authenticator
*wpa_auth
,
777 struct wpa_channel_info
*ci
)
779 if (!wpa_auth
->cb
->channel_info
)
781 return wpa_auth
->cb
->channel_info(wpa_auth
->cb_ctx
, ci
);
783 #endif /* CONFIG_OCV */
786 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
790 if (len
< 2 + sizeof(struct rsn_mdie
))
793 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
794 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
795 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
796 pos
+= MOBILITY_DOMAIN_ID_LEN
;
798 if (conf
->ft_over_ds
)
799 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
806 int wpa_write_ftie(struct wpa_auth_config
*conf
, int use_sha384
,
807 const u8
*r0kh_id
, size_t r0kh_id_len
,
808 const u8
*anonce
, const u8
*snonce
,
809 u8
*buf
, size_t len
, const u8
*subelem
,
812 u8
*pos
= buf
, *ielen
;
813 size_t hdrlen
= use_sha384
? sizeof(struct rsn_ftie_sha384
) :
814 sizeof(struct rsn_ftie
);
816 if (len
< 2 + hdrlen
+ 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
820 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
824 struct rsn_ftie_sha384
*hdr
= (struct rsn_ftie_sha384
*) pos
;
826 os_memset(hdr
, 0, sizeof(*hdr
));
828 WPA_PUT_LE16(hdr
->mic_control
, 0);
830 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
832 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
834 struct rsn_ftie
*hdr
= (struct rsn_ftie
*) pos
;
836 os_memset(hdr
, 0, sizeof(*hdr
));
838 WPA_PUT_LE16(hdr
->mic_control
, 0);
840 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
842 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
845 /* Optional Parameters */
846 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
847 *pos
++ = FT_R1KH_ID_LEN
;
848 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
849 pos
+= FT_R1KH_ID_LEN
;
852 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
853 *pos
++ = r0kh_id_len
;
854 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
859 os_memcpy(pos
, subelem
, subelem_len
);
863 *ielen
= pos
- buf
- 2;
869 /* A packet to be handled after seq response */
870 struct ft_remote_item
{
873 u8 nonce
[FT_RRB_NONCE_LEN
];
874 struct os_reltime nonce_ts
;
876 u8 src_addr
[ETH_ALEN
];
881 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
883 const u8
*enc
, size_t enc_len
,
884 const u8
*auth
, size_t auth_len
,
889 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
891 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
892 dl_list_del(&item
->list
);
893 bin_clear_free(item
->enc
, item
->enc_len
);
899 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
900 struct ft_remote_seq
*rkh_seq
, int cb
)
902 struct ft_remote_item
*item
, *n
;
904 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
905 struct ft_remote_item
, list
) {
907 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
908 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
909 wpa_ft_rrb_seq_free(item
);
914 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
916 struct ft_remote_item
*item
= timeout_ctx
;
918 wpa_ft_rrb_seq_free(item
);
923 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
924 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
925 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
926 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
927 const u8
*enc
, size_t enc_len
,
928 const u8
*auth
, size_t auth_len
,
929 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
931 const u8
*enc
, size_t enc_len
,
932 const u8
*auth
, size_t auth_len
,
935 struct ft_remote_item
*item
= NULL
;
938 struct tlv_list seq_req_auth
[] = {
939 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
940 .data
= NULL
/* to be filled: item->nonce */ },
941 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
943 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
945 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
948 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
949 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
953 wpa_printf(MSG_DEBUG
, "FT: Send out sequence number request to " MACSTR
,
955 item
= os_zalloc(sizeof(*item
));
959 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
962 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
963 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
967 if (os_get_reltime(&item
->nonce_ts
) < 0)
970 if (enc
&& enc_len
> 0) {
971 item
->enc
= os_memdup(enc
, enc_len
);
972 item
->enc_len
= enc_len
;
977 if (auth
&& auth_len
> 0) {
978 item
->auth
= os_memdup(auth
, auth_len
);
979 item
->auth_len
= auth_len
;
984 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
987 seq_req_auth
[0].data
= item
->nonce
;
989 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
990 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
991 &packet
, &packet_len
) < 0) {
992 item
= NULL
; /* some other seq resp might still accept this */
996 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
998 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
1005 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
1007 os_free(item
->auth
);
1008 bin_clear_free(item
->enc
, item
->enc_len
);
1016 #define FT_RRB_SEQ_OK 0
1017 #define FT_RRB_SEQ_DROP 1
1018 #define FT_RRB_SEQ_DEFER 2
1021 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1022 const u8
*enc
, size_t enc_len
,
1023 const u8
*auth
, size_t auth_len
,
1024 const char *msgtype
, int no_defer
)
1028 const struct ft_rrb_seq
*msg_both
;
1029 u32 msg_seq
, msg_off
, rkh_off
;
1030 struct os_reltime now
;
1033 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1034 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
1035 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1037 if (rkh_seq
->rx
.num_last
== 0) {
1038 /* first packet from remote */
1042 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
1043 /* remote might have rebooted */
1047 if (os_get_reltime(&now
) == 0) {
1048 u32 msg_ts_now_remote
, msg_ts_off
;
1049 struct os_reltime now_remote
;
1051 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
1052 msg_ts_now_remote
= now_remote
.sec
;
1053 msg_ts_off
= le_to_host32(msg_both
->ts
) -
1054 (msg_ts_now_remote
- ftRRBseqTimeout
);
1055 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
1059 msg_seq
= le_to_host32(msg_both
->seq
);
1060 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1061 msg_off
= msg_seq
- rkh_off
;
1062 if (msg_off
> 0xC0000000)
1063 goto out
; /* too old message, drop it */
1065 if (msg_off
<= 0x40000000) {
1066 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1067 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
1068 goto out
; /* duplicate message, drop it */
1071 return FT_RRB_SEQ_OK
;
1078 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
1079 MACSTR
, msgtype
, MAC2STR(src_addr
));
1081 return FT_RRB_SEQ_DEFER
;
1083 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
1084 msgtype
, MAC2STR(src_addr
));
1086 return FT_RRB_SEQ_DROP
;
1091 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
1092 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1093 const u8
*auth
, size_t auth_len
,
1094 const char *msgtype
)
1098 const struct ft_rrb_seq
*msg_both
;
1099 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
1103 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1104 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1106 msg_seq
= le_to_host32(msg_both
->seq
);
1108 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
1109 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
1110 rkh_seq
->rx
.num_last
++;
1114 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1115 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1116 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
1117 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
1118 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
1121 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
1122 rkh_seq
->rx
.offsetidx
= minidx
;
1126 /* RRB_GET_AUTH should never fail here as
1127 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1128 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
1132 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
1133 struct ft_rrb_seq
*f_seq
)
1135 struct os_reltime now
;
1137 if (os_get_reltime(&now
) < 0)
1140 if (!rkh_seq
->tx
.dom
) {
1141 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1142 sizeof(rkh_seq
->tx
.seq
))) {
1143 wpa_printf(MSG_ERROR
,
1144 "FT: Failed to get random data for sequence number initialization");
1145 rkh_seq
->tx
.seq
= now
.usec
;
1147 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1148 sizeof(rkh_seq
->tx
.dom
))) {
1149 wpa_printf(MSG_ERROR
,
1150 "FT: Failed to get random data for sequence number initialization");
1151 rkh_seq
->tx
.dom
= now
.usec
;
1153 rkh_seq
->tx
.dom
|= 1;
1156 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1157 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1158 f_seq
->ts
= host_to_le32(now
.sec
);
1166 struct wpa_ft_pmk_r0_sa
{
1167 struct dl_list list
;
1168 u8 pmk_r0
[PMK_LEN_MAX
];
1170 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1172 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1173 struct vlan_description
*vlan
;
1174 os_time_t expiration
; /* 0 for no expiration */
1176 size_t identity_len
;
1178 size_t radius_cui_len
;
1179 os_time_t session_timeout
; /* 0 for no expiration */
1180 /* TODO: radius_class, EAP type */
1184 struct wpa_ft_pmk_r1_sa
{
1185 struct dl_list list
;
1186 u8 pmk_r1
[PMK_LEN_MAX
];
1188 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1190 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1191 struct vlan_description
*vlan
;
1193 size_t identity_len
;
1195 size_t radius_cui_len
;
1196 os_time_t session_timeout
; /* 0 for no expiration */
1197 /* TODO: radius_class, EAP type */
1200 struct wpa_ft_pmk_cache
{
1201 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1202 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1206 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1207 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1210 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1215 dl_list_del(&r0
->list
);
1216 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1218 os_memset(r0
->pmk_r0
, 0, PMK_LEN_MAX
);
1220 os_free(r0
->identity
);
1221 os_free(r0
->radius_cui
);
1226 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1228 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1229 struct os_reltime now
;
1231 int session_timeout
;
1233 os_get_reltime(&now
);
1238 expires_in
= r0
->expiration
- now
.sec
;
1239 session_timeout
= r0
->session_timeout
- now
.sec
;
1240 /* conditions to remove from cache:
1241 * a) r0->expiration is set and hit
1243 * b) r0->session_timeout is set and hit
1245 if ((!r0
->expiration
|| expires_in
> 0) &&
1246 (!r0
->session_timeout
|| session_timeout
> 0)) {
1247 wpa_printf(MSG_ERROR
,
1248 "FT: %s() called for non-expired entry %p",
1250 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1251 if (r0
->expiration
&& expires_in
> 0)
1252 eloop_register_timeout(expires_in
+ 1, 0,
1253 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1254 if (r0
->session_timeout
&& session_timeout
> 0)
1255 eloop_register_timeout(session_timeout
+ 1, 0,
1256 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1260 wpa_ft_free_pmk_r0(r0
);
1264 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1269 dl_list_del(&r1
->list
);
1270 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1272 os_memset(r1
->pmk_r1
, 0, PMK_LEN_MAX
);
1274 os_free(r1
->identity
);
1275 os_free(r1
->radius_cui
);
1280 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1282 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1284 wpa_ft_free_pmk_r1(r1
);
1288 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1290 struct wpa_ft_pmk_cache
*cache
;
1292 cache
= os_zalloc(sizeof(*cache
));
1294 dl_list_init(&cache
->pmk_r0
);
1295 dl_list_init(&cache
->pmk_r1
);
1302 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1304 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1305 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1307 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1308 struct wpa_ft_pmk_r0_sa
, list
)
1309 wpa_ft_free_pmk_r0(r0
);
1311 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1312 struct wpa_ft_pmk_r1_sa
, list
)
1313 wpa_ft_free_pmk_r1(r1
);
1319 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1320 const u8
*spa
, const u8
*pmk_r0
,
1322 const u8
*pmk_r0_name
, int pairwise
,
1323 const struct vlan_description
*vlan
,
1324 int expires_in
, int session_timeout
,
1325 const u8
*identity
, size_t identity_len
,
1326 const u8
*radius_cui
, size_t radius_cui_len
)
1328 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1329 struct wpa_ft_pmk_r0_sa
*r0
;
1330 struct os_reltime now
;
1332 /* TODO: add limit on number of entries in cache */
1333 os_get_reltime(&now
);
1335 r0
= os_zalloc(sizeof(*r0
));
1339 os_memcpy(r0
->pmk_r0
, pmk_r0
, pmk_r0_len
);
1340 r0
->pmk_r0_len
= pmk_r0_len
;
1341 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1342 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1343 r0
->pairwise
= pairwise
;
1345 r0
->expiration
= now
.sec
+ expires_in
;
1346 if (vlan
&& vlan
->notempty
) {
1347 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1349 bin_clear_free(r0
, sizeof(*r0
));
1355 r0
->identity
= os_malloc(identity_len
);
1357 os_memcpy(r0
->identity
, identity
, identity_len
);
1358 r0
->identity_len
= identity_len
;
1362 r0
->radius_cui
= os_malloc(radius_cui_len
);
1363 if (r0
->radius_cui
) {
1364 os_memcpy(r0
->radius_cui
, radius_cui
, radius_cui_len
);
1365 r0
->radius_cui_len
= radius_cui_len
;
1368 if (session_timeout
> 0)
1369 r0
->session_timeout
= now
.sec
+ session_timeout
;
1371 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1373 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1375 if (session_timeout
> 0)
1376 eloop_register_timeout(session_timeout
+ 1, 0,
1377 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1383 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1384 const u8
*spa
, const u8
*pmk_r0_name
,
1385 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1387 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1388 struct wpa_ft_pmk_r0_sa
*r0
;
1389 struct os_reltime now
;
1391 os_get_reltime(&now
);
1392 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1393 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1394 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1395 WPA_PMK_NAME_LEN
) == 0) {
1406 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1407 const u8
*spa
, const u8
*pmk_r1
,
1409 const u8
*pmk_r1_name
, int pairwise
,
1410 const struct vlan_description
*vlan
,
1411 int expires_in
, int session_timeout
,
1412 const u8
*identity
, size_t identity_len
,
1413 const u8
*radius_cui
, size_t radius_cui_len
)
1415 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1416 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1417 struct wpa_ft_pmk_r1_sa
*r1
;
1418 struct os_reltime now
;
1420 /* TODO: limit on number of entries in cache */
1421 os_get_reltime(&now
);
1423 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1424 expires_in
= max_expires_in
;
1426 r1
= os_zalloc(sizeof(*r1
));
1430 os_memcpy(r1
->pmk_r1
, pmk_r1
, pmk_r1_len
);
1431 r1
->pmk_r1_len
= pmk_r1_len
;
1432 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1433 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1434 r1
->pairwise
= pairwise
;
1435 if (vlan
&& vlan
->notempty
) {
1436 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1438 bin_clear_free(r1
, sizeof(*r1
));
1444 r1
->identity
= os_malloc(identity_len
);
1446 os_memcpy(r1
->identity
, identity
, identity_len
);
1447 r1
->identity_len
= identity_len
;
1451 r1
->radius_cui
= os_malloc(radius_cui_len
);
1452 if (r1
->radius_cui
) {
1453 os_memcpy(r1
->radius_cui
, radius_cui
, radius_cui_len
);
1454 r1
->radius_cui_len
= radius_cui_len
;
1457 if (session_timeout
> 0)
1458 r1
->session_timeout
= now
.sec
+ session_timeout
;
1460 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1463 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1465 if (session_timeout
> 0)
1466 eloop_register_timeout(session_timeout
+ 1, 0,
1467 wpa_ft_expire_pmk_r1
, r1
, NULL
);
1473 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1474 const u8
*spa
, const u8
*pmk_r1_name
,
1475 u8
*pmk_r1
, size_t *pmk_r1_len
, int *pairwise
,
1476 struct vlan_description
*vlan
,
1477 const u8
**identity
, size_t *identity_len
,
1478 const u8
**radius_cui
, size_t *radius_cui_len
,
1479 int *session_timeout
)
1481 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1482 struct wpa_ft_pmk_r1_sa
*r1
;
1483 struct os_reltime now
;
1485 os_get_reltime(&now
);
1487 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1488 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1489 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1490 WPA_PMK_NAME_LEN
) == 0) {
1491 os_memcpy(pmk_r1
, r1
->pmk_r1
, r1
->pmk_r1_len
);
1492 *pmk_r1_len
= r1
->pmk_r1_len
;
1494 *pairwise
= r1
->pairwise
;
1495 if (vlan
&& r1
->vlan
)
1497 if (vlan
&& !r1
->vlan
)
1498 os_memset(vlan
, 0, sizeof(*vlan
));
1499 if (identity
&& identity_len
) {
1500 *identity
= r1
->identity
;
1501 *identity_len
= r1
->identity_len
;
1503 if (radius_cui
&& radius_cui_len
) {
1504 *radius_cui
= r1
->radius_cui
;
1505 *radius_cui_len
= r1
->radius_cui_len
;
1507 if (session_timeout
&& r1
->session_timeout
> now
.sec
)
1508 *session_timeout
= r1
->session_timeout
-
1510 else if (session_timeout
&& r1
->session_timeout
)
1511 *session_timeout
= 1;
1512 else if (session_timeout
)
1513 *session_timeout
= 0;
1522 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1527 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1529 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1533 dl_list_init(&r0kh
->seq
->rx
.queue
);
1539 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1540 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1541 struct ft_remote_r0kh
**r0kh_out
,
1542 struct ft_remote_r0kh
**r0kh_wildcard
)
1544 struct ft_remote_r0kh
*r0kh
;
1546 *r0kh_wildcard
= NULL
;
1549 if (wpa_auth
->conf
.r0kh_list
)
1550 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1553 for (; r0kh
; r0kh
= r0kh
->next
) {
1554 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1555 *r0kh_wildcard
= r0kh
;
1556 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1557 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1561 if (!*r0kh_out
&& !*r0kh_wildcard
)
1562 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1564 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1569 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1574 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1576 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1580 dl_list_init(&r1kh
->seq
->rx
.queue
);
1586 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1587 const u8
*f_r1kh_id
,
1588 struct ft_remote_r1kh
**r1kh_out
,
1589 struct ft_remote_r1kh
**r1kh_wildcard
)
1591 struct ft_remote_r1kh
*r1kh
;
1593 *r1kh_wildcard
= NULL
;
1596 if (wpa_auth
->conf
.r1kh_list
)
1597 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1600 for (; r1kh
; r1kh
= r1kh
->next
) {
1601 if (is_zero_ether_addr(r1kh
->addr
) &&
1602 is_zero_ether_addr(r1kh
->id
))
1603 *r1kh_wildcard
= r1kh
;
1605 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1609 if (!*r1kh_out
&& !*r1kh_wildcard
)
1610 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1612 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1617 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1618 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1620 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1621 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1622 f_r0kh_id_len
) != 0)
1629 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1630 const u8
*f_r1kh_id
)
1632 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1633 FT_R1KH_ID_LEN
) != 0)
1640 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1642 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1643 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1645 if (!wpa_auth
->conf
.r0kh_list
)
1648 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1649 if (r0kh
== timeout_ctx
)
1656 prev
->next
= r0kh
->next
;
1658 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1660 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1666 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1667 struct ft_remote_r0kh
*r0kh
, int timeout
)
1670 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1675 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1676 struct ft_remote_r0kh
*r0kh
, int timeout
)
1678 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1681 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1686 static struct ft_remote_r0kh
*
1687 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1688 struct ft_remote_r0kh
*r0kh_wildcard
,
1689 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1692 struct ft_remote_r0kh
*r0kh
;
1694 if (!wpa_auth
->conf
.r0kh_list
)
1697 r0kh
= os_zalloc(sizeof(*r0kh
));
1702 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1704 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1705 id_len
= FT_R0KH_ID_MAX_LEN
;
1706 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1707 r0kh
->id_len
= id_len
;
1709 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1711 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1712 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1715 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1718 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1725 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1727 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1728 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1730 if (!wpa_auth
->conf
.r1kh_list
)
1733 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1734 if (r1kh
== timeout_ctx
)
1741 prev
->next
= r1kh
->next
;
1743 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1745 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1751 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1752 struct ft_remote_r1kh
*r1kh
, int timeout
)
1755 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1760 static struct ft_remote_r1kh
*
1761 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1762 struct ft_remote_r1kh
*r1kh_wildcard
,
1763 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1765 struct ft_remote_r1kh
*r1kh
;
1767 if (!wpa_auth
->conf
.r1kh_list
)
1770 r1kh
= os_zalloc(sizeof(*r1kh
));
1774 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1775 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1776 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1777 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1778 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1781 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1784 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1791 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1793 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1797 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1799 struct ft_remote_r0kh
*r0kh
;
1800 struct ft_remote_r1kh
*r1kh
;
1802 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1804 if (wpa_auth
->conf
.r0kh_list
)
1805 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1808 for (; r0kh
; r0kh
= r0kh
->next
) {
1811 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1816 if (wpa_auth
->conf
.r1kh_list
)
1817 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1820 for (; r1kh
; r1kh
= r1kh
->next
) {
1823 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1830 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1832 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1833 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1835 if (wpa_auth
->conf
.r0kh_list
)
1836 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1840 r0kh_next
= r0kh
->next
;
1841 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1844 r0kh_prev
->next
= r0kh_next
;
1846 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1854 if (wpa_auth
->conf
.r1kh_list
)
1855 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1859 r1kh_next
= r1kh
->next
;
1860 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1863 r1kh_prev
->next
= r1kh_next
;
1865 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1875 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1877 wpa_ft_deinit_seq(wpa_auth
);
1878 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1882 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1883 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1885 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1887 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1890 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1891 &r0kh
, &r0kh_wildcard
);
1893 if (!r0kh_wildcard
) {
1894 /* r0kh removed after neg_timeout and might need re-adding */
1898 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1899 f_r0kh_id
, f_r0kh_id_len
);
1902 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1903 wpa_auth
->conf
.rkh_neg_timeout
);
1904 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1906 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1908 wpa_auth
->conf
.rkh_neg_timeout
);
1912 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1914 struct wpa_state_machine
*sm
= eloop_ctx
;
1916 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1918 if (sm
->ft_pending_pull_left_retries
<= 0)
1919 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1921 /* cancel multiple timeouts */
1922 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1927 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1928 const u8
*ies
, size_t ies_len
,
1929 const u8
*pmk_r0_name
)
1931 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1933 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1934 size_t packet_len
, key_len
;
1935 struct ft_rrb_seq f_seq
;
1936 int tsecs
, tusecs
, first
;
1937 struct wpabuf
*ft_pending_req_ies
;
1939 struct tlv_list req_enc
[] = {
1940 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1941 .data
= pmk_r0_name
},
1942 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1944 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1946 struct tlv_list req_auth
[] = {
1947 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1948 .data
= sm
->ft_pending_pull_nonce
},
1949 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1950 .data
= (u8
*) &f_seq
},
1951 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1952 .data
= sm
->r0kh_id
},
1953 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1954 .data
= f_r1kh_id
},
1955 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1958 if (sm
->ft_pending_pull_left_retries
<= 0)
1960 first
= sm
->ft_pending_pull_left_retries
==
1961 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1962 sm
->ft_pending_pull_left_retries
--;
1964 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1965 &r0kh
, &r0kh_wildcard
);
1967 /* Keep r0kh sufficiently long in the list for seq num check */
1968 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1969 1 + ftRRBseqTimeout
;
1971 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1972 } else if (r0kh_wildcard
) {
1973 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1974 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1975 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1976 r0kh_wildcard
->addr
,
1977 sm
->r0kh_id
, sm
->r0kh_id_len
,
1981 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1982 sm
->r0kh_id
, sm
->r0kh_id_len
);
1985 if (is_zero_ether_addr(r0kh
->addr
)) {
1986 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1987 sm
->r0kh_id
, sm
->r0kh_id_len
);
1990 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1991 wpa_printf(MSG_DEBUG
,
1992 "FT: R0KH-ID points to self - no matching key available");
1997 key_len
= sizeof(r0kh
->key
);
1999 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
2000 "address " MACSTR
, MAC2STR(r0kh
->addr
));
2002 if (r0kh
->seq
->rx
.num_last
== 0) {
2003 /* A sequence request will be sent out anyway when pull
2004 * response is received. Send it out now to avoid one RTT. */
2005 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
2006 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
2007 key_len
, NULL
, 0, NULL
, 0, NULL
);
2011 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
2012 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2017 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
2018 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
2022 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
2023 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
2024 &packet
, &packet_len
) < 0)
2027 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
2028 wpabuf_free(sm
->ft_pending_req_ies
);
2029 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
2030 if (!sm
->ft_pending_req_ies
) {
2035 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
2036 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
2037 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
2039 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
2040 packet
, packet_len
);
2048 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
2049 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
2051 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2052 struct vlan_description vlan
;
2053 const u8
*identity
, *radius_cui
;
2054 size_t identity_len
, radius_cui_len
;
2055 int session_timeout
;
2056 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2057 SHA384_MAC_LEN
: PMK_LEN
;
2059 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2060 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2065 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2066 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2068 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2070 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2071 pmk_r0_name
, sm
->pairwise
, &vlan
, expires_in
,
2072 session_timeout
, identity
, identity_len
,
2073 radius_cui
, radius_cui_len
);
2077 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, struct wpa_ptk
*ptk
)
2079 u8 pmk_r0
[PMK_LEN_MAX
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2080 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2081 SHA384_MAC_LEN
: PMK_LEN
;
2082 size_t pmk_r1_len
= pmk_r0_len
;
2083 u8 pmk_r1
[PMK_LEN_MAX
];
2084 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2085 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
2086 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
2087 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
2088 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
2089 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
2090 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
2091 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
2092 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2093 struct vlan_description vlan
;
2094 const u8
*identity
, *radius_cui
;
2095 size_t identity_len
, radius_cui_len
;
2096 int session_timeout
;
2098 if (sm
->xxkey_len
== 0) {
2099 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
2104 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2105 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2110 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2111 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2113 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2115 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
2116 r0kh
, r0kh_len
, sm
->addr
,
2117 pmk_r0
, pmk_r0_name
,
2118 wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
)) < 0)
2120 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, pmk_r0_len
);
2121 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
2122 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2123 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2125 sm
->pairwise
, &vlan
, expires_in
,
2126 session_timeout
, identity
, identity_len
,
2127 radius_cui
, radius_cui_len
);
2129 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
, r1kh
, sm
->addr
,
2130 pmk_r1
, sm
->pmk_r1_name
) < 0)
2132 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, pmk_r1_len
);
2133 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
2135 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2136 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
, pmk_r1_len
,
2137 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
2138 expires_in
, session_timeout
, identity
,
2139 identity_len
, radius_cui
, radius_cui_len
);
2141 return wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2142 sm
->addr
, sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
2143 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
2147 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
2148 const u8
*addr
, int idx
, u8
*seq
)
2150 if (wpa_auth
->cb
->get_seqnum
== NULL
)
2152 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
2156 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2159 struct wpa_group
*gsm
= sm
->group
;
2160 size_t subelem_len
, pad_len
;
2167 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2169 kek_len
= sm
->PTK
.kek2_len
;
2172 kek_len
= sm
->PTK
.kek_len
;
2175 key_len
= gsm
->GTK_len
;
2176 if (key_len
> sizeof(keybuf
))
2180 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2183 pad_len
= key_len
% 8;
2185 pad_len
= 8 - pad_len
;
2186 if (key_len
+ pad_len
< 16)
2188 if (pad_len
&& key_len
< sizeof(keybuf
)) {
2189 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
2190 os_memset(keybuf
+ key_len
, 0, pad_len
);
2191 keybuf
[key_len
] = 0xdd;
2195 key
= gsm
->GTK
[gsm
->GN
- 1];
2198 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
2201 subelem_len
= 13 + key_len
+ 8;
2202 subelem
= os_zalloc(subelem_len
);
2203 if (subelem
== NULL
)
2206 subelem
[0] = FTIE_SUBELEM_GTK
;
2207 subelem
[1] = 11 + key_len
+ 8;
2208 /* Key ID in B0-B1 of Key Info */
2209 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
2210 subelem
[4] = gsm
->GTK_len
;
2211 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
2212 if (aes_wrap(kek
, kek_len
, key_len
/ 8, key
, subelem
+ 13)) {
2213 wpa_printf(MSG_DEBUG
,
2214 "FT: GTK subelem encryption failed: kek_len=%d",
2225 #ifdef CONFIG_IEEE80211W
2226 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2229 struct wpa_group
*gsm
= sm
->group
;
2235 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2237 kek_len
= sm
->PTK
.kek2_len
;
2240 kek_len
= sm
->PTK
.kek_len
;
2243 igtk_len
= wpa_cipher_key_len(sm
->wpa_auth
->conf
.group_mgmt_cipher
);
2245 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2247 subelem_len
= 1 + 1 + 2 + 6 + 1 + igtk_len
+ 8;
2248 subelem
= os_zalloc(subelem_len
);
2249 if (subelem
== NULL
)
2253 *pos
++ = FTIE_SUBELEM_IGTK
;
2254 *pos
++ = subelem_len
- 2;
2255 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
2257 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
2260 if (aes_wrap(kek
, kek_len
, igtk_len
/ 8,
2261 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
2262 wpa_printf(MSG_DEBUG
,
2263 "FT: IGTK subelem encryption failed: kek_len=%d",
2272 #endif /* CONFIG_IEEE80211W */
2275 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
2276 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
2277 const u8
*ies
, size_t ies_len
)
2279 struct ieee802_11_elems parse
;
2280 struct rsn_rdie
*rdie
;
2282 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
2284 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
2287 if (end
- pos
< (int) sizeof(*rdie
)) {
2288 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
2292 *pos
++ = WLAN_EID_RIC_DATA
;
2293 *pos
++ = sizeof(*rdie
);
2294 rdie
= (struct rsn_rdie
*) pos
;
2296 rdie
->descr_count
= 0;
2297 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2298 pos
+= sizeof(*rdie
);
2300 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2302 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2304 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2308 if (parse
.wmm_tspec
) {
2309 struct wmm_tspec_element
*tspec
;
2311 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2312 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2313 "(%d)", (int) parse
.wmm_tspec_len
);
2315 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2318 if (end
- pos
< (int) sizeof(*tspec
)) {
2319 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2322 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2325 tspec
= (struct wmm_tspec_element
*) pos
;
2326 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2330 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2333 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2334 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2335 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2337 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2338 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2340 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2342 /* TSPEC accepted; include updated TSPEC in response */
2343 rdie
->descr_count
= 1;
2344 pos
+= sizeof(struct wmm_tspec_element
);
2348 #endif /* NEED_AP_MLME */
2350 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2353 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2354 sizeof(struct wmm_tspec_element
));
2357 rdie
->status_code
= host_to_le16(res
);
2359 /* TSPEC accepted; include updated TSPEC in
2361 rdie
->descr_count
= 1;
2362 pos
+= sizeof(struct wmm_tspec_element
);
2368 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2369 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2374 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2375 const u8
*ric
, size_t ric_len
)
2377 const u8
*rpos
, *start
;
2378 const struct rsn_rdie
*rdie
;
2380 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2383 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2384 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2385 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2387 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2388 rpos
+= 2 + rpos
[1];
2391 while (rpos
+ 2 <= ric
+ ric_len
&&
2392 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2393 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2395 rpos
+= 2 + rpos
[1];
2397 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2399 start
, rpos
- start
);
2406 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2407 size_t max_len
, int auth_alg
,
2408 const u8
*req_ies
, size_t req_ies_len
)
2410 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2411 u8
*fte_mic
, *elem_count
;
2412 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2414 struct wpa_auth_config
*conf
;
2415 struct wpa_ft_ies parse
;
2417 u8
*anonce
, *snonce
;
2425 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
2426 conf
= &sm
->wpa_auth
->conf
;
2428 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2431 end
= pos
+ max_len
;
2433 if (auth_alg
== WLAN_AUTH_FT
||
2434 ((auth_alg
== WLAN_AUTH_FILS_SK
||
2435 auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
2436 auth_alg
== WLAN_AUTH_FILS_PK
) &&
2437 (sm
->wpa_key_mgmt
& (WPA_KEY_MGMT_FT_FILS_SHA256
|
2438 WPA_KEY_MGMT_FT_FILS_SHA384
)))) {
2439 if (!sm
->pmk_r1_name_valid
) {
2440 wpa_printf(MSG_ERROR
,
2441 "FT: PMKR1Name is not valid for Assoc Resp RSNE");
2444 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name for Assoc Resp RSNE",
2445 sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
);
2447 * RSN (only present if this is a Reassociation Response and
2448 * part of a fast BSS transition; or if this is a
2449 * (Re)Association Response frame during an FT initial mobility
2450 * domain association using FILS)
2452 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2460 /* Mobility Domain Information */
2461 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2468 /* Fast BSS Transition Information */
2469 if (auth_alg
== WLAN_AUTH_FT
) {
2470 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2472 wpa_printf(MSG_DEBUG
,
2473 "FT: Failed to add GTK subelement");
2476 r0kh_id
= sm
->r0kh_id
;
2477 r0kh_id_len
= sm
->r0kh_id_len
;
2478 anonce
= sm
->ANonce
;
2479 snonce
= sm
->SNonce
;
2480 #ifdef CONFIG_IEEE80211W
2481 if (sm
->mgmt_frame_prot
) {
2485 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2487 wpa_printf(MSG_DEBUG
,
2488 "FT: Failed to add IGTK subelement");
2492 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2499 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2500 subelem_len
+= igtk_len
;
2503 #endif /* CONFIG_IEEE80211W */
2505 if (wpa_auth_uses_ocv(sm
)) {
2506 struct wpa_channel_info ci
;
2509 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
2510 wpa_printf(MSG_WARNING
,
2511 "Failed to get channel info for OCI element");
2516 subelem_len
+= 2 + OCV_OCI_LEN
;
2517 nbuf
= os_realloc(subelem
, subelem_len
);
2524 ocipos
= subelem
+ subelem_len
- 2 - OCV_OCI_LEN
;
2525 *ocipos
++ = FTIE_SUBELEM_OCI
;
2526 *ocipos
++ = OCV_OCI_LEN
;
2527 if (ocv_insert_oci(&ci
, &ocipos
) < 0) {
2532 #endif /* CONFIG_OCV */
2534 r0kh_id
= conf
->r0_key_holder
;
2535 r0kh_id_len
= conf
->r0_key_holder_len
;
2539 res
= wpa_write_ftie(conf
, use_sha384
, r0kh_id
, r0kh_id_len
,
2540 anonce
, snonce
, pos
, end
- pos
,
2541 subelem
, subelem_len
);
2550 struct rsn_ftie_sha384
*_ftie
=
2551 (struct rsn_ftie_sha384
*) (ftie
+ 2);
2553 fte_mic
= _ftie
->mic
;
2554 elem_count
= &_ftie
->mic_control
[1];
2556 struct rsn_ftie
*_ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2558 fte_mic
= _ftie
->mic
;
2559 elem_count
= &_ftie
->mic_control
[1];
2561 if (auth_alg
== WLAN_AUTH_FT
)
2562 *elem_count
= 3; /* Information element count */
2565 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
, use_sha384
) == 0
2567 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2569 if (auth_alg
== WLAN_AUTH_FT
)
2571 ieee802_11_ie_count(ric_start
,
2574 if (ric_start
== pos
)
2577 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2579 kck_len
= sm
->PTK
.kck2_len
;
2582 kck_len
= sm
->PTK
.kck_len
;
2584 if (auth_alg
== WLAN_AUTH_FT
&&
2585 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2586 mdie
, mdie_len
, ftie
, ftie_len
,
2588 ric_start
, ric_start
? pos
- ric_start
: 0,
2590 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2594 os_free(sm
->assoc_resp_ftie
);
2595 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2596 if (!sm
->assoc_resp_ftie
)
2598 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2604 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2606 enum wpa_alg alg
, const u8
*addr
, int idx
,
2607 u8
*key
, size_t key_len
)
2609 if (wpa_auth
->cb
->set_key
== NULL
)
2611 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2616 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
2621 /* MLME-SETKEYS.request(PTK) */
2622 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2623 klen
= wpa_cipher_key_len(sm
->pairwise
);
2624 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2625 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2626 "PTK configuration", sm
->pairwise
);
2630 if (sm
->tk_already_set
) {
2631 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2632 * PN in the driver */
2633 wpa_printf(MSG_DEBUG
,
2634 "FT: Do not re-install same PTK to the driver");
2638 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2639 * most likely without this.. At the moment, STA entry is added only
2640 * after association has been completed. This function will be called
2641 * again after association to get the PTK configured, but that could be
2642 * optimized by adding the STA entry earlier.
2644 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
2648 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2649 sm
->pairwise_set
= TRUE
;
2650 sm
->tk_already_set
= TRUE
;
2654 /* Derive PMK-R1 from PSK, check all available PSK */
2655 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2656 const u8
*req_pmk_r1_name
,
2657 u8
*out_pmk_r1
, int *out_pairwise
,
2658 struct vlan_description
*out_vlan
,
2659 const u8
**out_identity
, size_t *out_identity_len
,
2660 const u8
**out_radius_cui
,
2661 size_t *out_radius_cui_len
,
2662 int *out_session_timeout
)
2664 const u8
*pmk
= NULL
;
2665 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2666 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2667 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2668 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2669 const u8
*r0kh
= sm
->r0kh_id
;
2670 size_t r0kh_len
= sm
->r0kh_id_len
;
2671 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2672 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2673 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2676 pairwise
= sm
->pairwise
;
2679 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2684 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2686 pmk_r0
, pmk_r0_name
, 0) < 0 ||
2687 wpa_derive_pmk_r1(pmk_r0
, PMK_LEN
, pmk_r0_name
, r1kh
,
2688 sm
->addr
, pmk_r1
, pmk_r1_name
) < 0 ||
2689 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2690 WPA_PMK_NAME_LEN
) != 0)
2693 /* We found a PSK that matches the requested pmk_r1_name */
2694 wpa_printf(MSG_DEBUG
,
2695 "FT: Found PSK to generate PMK-R1 locally");
2696 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2698 *out_pairwise
= pairwise
;
2699 os_memcpy(sm
->PMK
, pmk
, PMK_LEN
);
2700 sm
->pmk_len
= PMK_LEN
;
2702 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2703 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2704 MACSTR
, MAC2STR(sm
->addr
));
2708 if (out_identity
&& out_identity_len
) {
2709 *out_identity_len
= wpa_ft_get_identity(
2710 sm
->wpa_auth
, sm
->addr
, out_identity
);
2713 if (out_radius_cui
&& out_radius_cui_len
) {
2714 *out_radius_cui_len
= wpa_ft_get_radius_cui(
2715 sm
->wpa_auth
, sm
->addr
, out_radius_cui
);
2718 if (out_session_timeout
) {
2719 *out_session_timeout
= wpa_ft_get_session_timeout(
2720 sm
->wpa_auth
, sm
->addr
);
2726 wpa_printf(MSG_DEBUG
,
2727 "FT: Did not find PSK to generate PMK-R1 locally");
2732 /* Detect the configuration the station asked for.
2733 * Required to detect FT-PSK and pairwise cipher.
2735 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2736 struct wpa_ft_ies
*parse
)
2738 int key_mgmt
, ciphers
;
2740 if (sm
->wpa_key_mgmt
)
2743 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2745 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2746 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2749 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2750 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2751 #ifdef CONFIG_SHA384
2752 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X_SHA384
)
2753 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X_SHA384
;
2754 #endif /* CONFIG_SHA384 */
2755 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2756 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2758 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2759 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2760 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2761 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2762 #endif /* CONFIG_FILS */
2763 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2765 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2767 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2770 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2776 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2777 struct wpa_state_machine
*sm
,
2778 const u8
*r0kh_id
, size_t r0kh_id_len
,
2779 const u8
*req_pmk_r0_name
,
2780 const u8
*req_pmk_r1_name
,
2781 u8
*out_pmk_r1
, int *out_pairwise
,
2782 struct vlan_description
*vlan
,
2783 const u8
**identity
, size_t *identity_len
,
2784 const u8
**radius_cui
,
2785 size_t *radius_cui_len
,
2786 int *out_session_timeout
)
2788 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2789 const struct wpa_ft_pmk_r0_sa
*r0
;
2790 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2792 int session_timeout
= 0;
2793 struct os_reltime now
;
2795 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2796 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2798 return -1; /* not our R0KH-ID */
2800 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2801 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2803 return -1; /* no matching PMKR0Name in local cache */
2805 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2807 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_len
, r0
->pmk_r0_name
,
2808 conf
->r1_key_holder
,
2809 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2811 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, r0
->pmk_r0_len
);
2812 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2814 os_get_reltime(&now
);
2816 expires_in
= r0
->expiration
- now
.sec
;
2818 if (r0
->session_timeout
)
2819 session_timeout
= r0
->session_timeout
- now
.sec
;
2821 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, r0
->pmk_r0_len
,
2823 sm
->pairwise
, r0
->vlan
, expires_in
, session_timeout
,
2824 r0
->identity
, r0
->identity_len
,
2825 r0
->radius_cui
, r0
->radius_cui_len
);
2827 *out_pairwise
= sm
->pairwise
;
2832 os_memset(vlan
, 0, sizeof(*vlan
));
2835 if (identity
&& identity_len
) {
2836 *identity
= r0
->identity
;
2837 *identity_len
= r0
->identity_len
;
2840 if (radius_cui
&& radius_cui_len
) {
2841 *radius_cui
= r0
->radius_cui
;
2842 *radius_cui_len
= r0
->radius_cui_len
;
2845 *out_session_timeout
= session_timeout
;
2851 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2852 const u8
*ies
, size_t ies_len
,
2853 u8
**resp_ies
, size_t *resp_ies_len
)
2855 struct rsn_mdie
*mdie
;
2856 u8 pmk_r1
[PMK_LEN_MAX
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2857 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2858 struct wpa_auth_config
*conf
;
2859 struct wpa_ft_ies parse
;
2863 int pairwise
, session_timeout
= 0;
2864 struct vlan_description vlan
;
2865 const u8
*identity
, *radius_cui
;
2866 size_t identity_len
= 0, radius_cui_len
= 0;
2873 sm
->pmk_r1_name_valid
= 0;
2874 conf
= &sm
->wpa_auth
->conf
;
2876 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2879 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, -1)) {
2880 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2881 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2883 use_sha384
= wpa_key_mgmt_sha384(parse
.key_mgmt
);
2884 pmk_r1_len
= use_sha384
? SHA384_MAC_LEN
: PMK_LEN
;
2886 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2887 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2888 os_memcmp(mdie
->mobility_domain
,
2889 sm
->wpa_auth
->conf
.mobility_domain
,
2890 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2891 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2892 return WLAN_STATUS_INVALID_MDIE
;
2896 struct rsn_ftie_sha384
*ftie
;
2898 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
2899 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2900 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2901 return WLAN_STATUS_INVALID_FTIE
;
2904 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2906 struct rsn_ftie
*ftie
;
2908 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2909 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2910 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2911 return WLAN_STATUS_INVALID_FTIE
;
2914 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2917 if (parse
.r0kh_id
== NULL
) {
2918 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2919 return WLAN_STATUS_INVALID_FTIE
;
2922 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2923 parse
.r0kh_id
, parse
.r0kh_id_len
);
2924 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2925 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2927 if (parse
.rsn_pmkid
== NULL
) {
2928 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2929 return WLAN_STATUS_INVALID_PMKID
;
2932 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2933 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2935 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2936 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2937 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2938 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2939 pmk_r1_name
, use_sha384
) < 0)
2940 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2941 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2942 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2944 if (conf
->ft_psk_generate_local
&&
2945 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2946 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
2947 &vlan
, &identity
, &identity_len
,
2948 &radius_cui
, &radius_cui_len
,
2949 &session_timeout
) < 0)
2950 return WLAN_STATUS_INVALID_PMKID
;
2951 wpa_printf(MSG_DEBUG
,
2952 "FT: Generated PMK-R1 for FT-PSK locally");
2953 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2954 pmk_r1
, &pmk_r1_len
, &pairwise
, &vlan
,
2955 &identity
, &identity_len
, &radius_cui
,
2956 &radius_cui_len
, &session_timeout
) < 0) {
2957 wpa_printf(MSG_DEBUG
,
2958 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2959 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2960 parse
.r0kh_id
, parse
.r0kh_id_len
,
2962 pmk_r1_name
, pmk_r1
, &pairwise
,
2963 &vlan
, &identity
, &identity_len
,
2964 &radius_cui
, &radius_cui_len
,
2965 &session_timeout
) == 0) {
2966 wpa_printf(MSG_DEBUG
,
2967 "FT: Generated PMK-R1 based on local PMK-R0");
2968 goto pmk_r1_derived
;
2971 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2972 wpa_printf(MSG_DEBUG
,
2973 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2974 return WLAN_STATUS_INVALID_PMKID
;
2977 return -1; /* Status pending */
2979 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2983 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, pmk_r1_len
);
2984 sm
->pmk_r1_name_valid
= 1;
2985 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2986 os_memcpy(sm
->pmk_r1
, pmk_r1
, pmk_r1_len
);
2987 sm
->pmk_r1_len
= pmk_r1_len
;
2989 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2990 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2992 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2995 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2996 sm
->SNonce
, WPA_NONCE_LEN
);
2997 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2998 sm
->ANonce
, WPA_NONCE_LEN
);
3000 if (wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
3001 sm
->addr
, sm
->wpa_auth
->addr
, pmk_r1_name
,
3002 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
3004 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3006 sm
->pairwise
= pairwise
;
3007 sm
->PTK_valid
= TRUE
;
3008 sm
->tk_already_set
= FALSE
;
3009 wpa_ft_install_ptk(sm
);
3011 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
3012 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
3013 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3015 if (wpa_ft_set_identity(sm
->wpa_auth
, sm
->addr
,
3016 identity
, identity_len
) < 0 ||
3017 wpa_ft_set_radius_cui(sm
->wpa_auth
, sm
->addr
,
3018 radius_cui
, radius_cui_len
) < 0) {
3019 wpa_printf(MSG_DEBUG
, "FT: Failed to configure identity/CUI");
3020 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3022 wpa_ft_set_session_timeout(sm
->wpa_auth
, sm
->addr
, session_timeout
);
3024 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
3025 2 + FT_R1KH_ID_LEN
+ 200;
3026 *resp_ies
= os_zalloc(buflen
);
3027 if (*resp_ies
== NULL
)
3031 end
= *resp_ies
+ buflen
;
3033 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
3038 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
3043 ret
= wpa_write_ftie(conf
, use_sha384
, parse
.r0kh_id
, parse
.r0kh_id_len
,
3044 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
3049 *resp_ies_len
= pos
- *resp_ies
;
3051 return WLAN_STATUS_SUCCESS
;
3055 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3059 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
3060 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
3061 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
3062 u16 auth_transaction
, u16 status
,
3063 const u8
*ies
, size_t ies_len
),
3068 size_t resp_ies_len
;
3072 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
3073 "WPA SM not available");
3077 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
3078 " BSSID=" MACSTR
" transaction=%d",
3079 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
3080 sm
->ft_pending_cb
= cb
;
3081 sm
->ft_pending_cb_ctx
= ctx
;
3082 sm
->ft_pending_auth_transaction
= auth_transaction
;
3083 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3084 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
3087 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
3092 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
3093 " auth_transaction=%d status=%d",
3094 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
3095 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3096 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
3097 resp_ies
, resp_ies_len
);
3102 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
3105 struct wpa_ft_ies parse
;
3106 struct rsn_mdie
*mdie
;
3107 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
3108 size_t mic_len
= 16;
3113 const u8
*anonce
, *snonce
, *fte_mic
;
3117 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3119 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
3121 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
3123 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, use_sha384
) < 0) {
3124 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
3125 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3128 if (parse
.rsn
== NULL
) {
3129 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
3130 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3133 if (parse
.rsn_pmkid
== NULL
) {
3134 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
3135 return WLAN_STATUS_INVALID_PMKID
;
3138 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
3140 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
3141 "with the PMKR1Name derived from auth request");
3142 return WLAN_STATUS_INVALID_PMKID
;
3145 mdie
= (struct rsn_mdie
*) parse
.mdie
;
3146 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
3147 os_memcmp(mdie
->mobility_domain
,
3148 sm
->wpa_auth
->conf
.mobility_domain
,
3149 MOBILITY_DOMAIN_ID_LEN
) != 0) {
3150 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
3151 return WLAN_STATUS_INVALID_MDIE
;
3155 struct rsn_ftie_sha384
*ftie
;
3157 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
3158 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3159 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3160 return WLAN_STATUS_INVALID_FTIE
;
3163 anonce
= ftie
->anonce
;
3164 snonce
= ftie
->snonce
;
3165 fte_elem_count
= ftie
->mic_control
[1];
3166 fte_mic
= ftie
->mic
;
3168 struct rsn_ftie
*ftie
;
3170 ftie
= (struct rsn_ftie
*) parse
.ftie
;
3171 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3172 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3173 return WLAN_STATUS_INVALID_FTIE
;
3176 anonce
= ftie
->anonce
;
3177 snonce
= ftie
->snonce
;
3178 fte_elem_count
= ftie
->mic_control
[1];
3179 fte_mic
= ftie
->mic
;
3182 if (os_memcmp(snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
3183 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
3184 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
3185 snonce
, WPA_NONCE_LEN
);
3186 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
3187 sm
->SNonce
, WPA_NONCE_LEN
);
3188 return WLAN_STATUS_INVALID_FTIE
;
3191 if (os_memcmp(anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
3192 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
3193 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
3194 anonce
, WPA_NONCE_LEN
);
3195 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
3196 sm
->ANonce
, WPA_NONCE_LEN
);
3197 return WLAN_STATUS_INVALID_FTIE
;
3201 if (parse
.r0kh_id
== NULL
) {
3202 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
3203 return WLAN_STATUS_INVALID_FTIE
;
3206 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
3207 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
3209 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
3210 "the current R0KH-ID");
3211 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
3212 parse
.r0kh_id
, parse
.r0kh_id_len
);
3213 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
3214 sm
->r0kh_id
, sm
->r0kh_id_len
);
3215 return WLAN_STATUS_INVALID_FTIE
;
3218 if (parse
.r1kh_id
== NULL
) {
3219 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
3220 return WLAN_STATUS_INVALID_FTIE
;
3223 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
3224 FT_R1KH_ID_LEN
) != 0) {
3225 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
3227 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
3228 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
3229 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
3230 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
3231 return WLAN_STATUS_INVALID_FTIE
;
3234 if (parse
.rsn_pmkid
== NULL
||
3235 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
3237 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
3238 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
3239 return WLAN_STATUS_INVALID_PMKID
;
3244 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
3245 if (fte_elem_count
!= count
) {
3246 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
3247 "Control: received %u expected %u",
3248 fte_elem_count
, count
);
3249 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3252 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
3254 kck_len
= sm
->PTK
.kck2_len
;
3257 kck_len
= sm
->PTK
.kck_len
;
3259 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
3260 parse
.mdie
- 2, parse
.mdie_len
+ 2,
3261 parse
.ftie
- 2, parse
.ftie_len
+ 2,
3262 parse
.rsn
- 2, parse
.rsn_len
+ 2,
3263 parse
.ric
, parse
.ric_len
,
3265 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
3266 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3269 if (os_memcmp_const(mic
, fte_mic
, mic_len
) != 0) {
3270 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
3271 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
3272 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
3273 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
3275 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
3276 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
3277 parse
.mdie
- 2, parse
.mdie_len
+ 2);
3278 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
3279 parse
.ftie
- 2, parse
.ftie_len
+ 2);
3280 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
3281 parse
.rsn
- 2, parse
.rsn_len
+ 2);
3282 return WLAN_STATUS_INVALID_FTIE
;
3286 if (wpa_auth_uses_ocv(sm
)) {
3287 struct wpa_channel_info ci
;
3291 if (wpa_channel_info(sm
->wpa_auth
, &ci
) != 0) {
3292 wpa_printf(MSG_WARNING
,
3293 "Failed to get channel info to validate received OCI in (Re)Assoc Request");
3294 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3297 if (get_sta_tx_parameters(sm
,
3298 channel_width_to_int(ci
.chanwidth
),
3299 ci
.seg1_idx
, &tx_chanwidth
,
3301 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3303 if (ocv_verify_tx_params(parse
.oci
, parse
.oci_len
, &ci
,
3304 tx_chanwidth
, tx_seg1_idx
) != 0) {
3305 wpa_printf(MSG_WARNING
, "%s", ocv_errorstr
);
3306 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3309 #endif /* CONFIG_OCV */
3311 return WLAN_STATUS_SUCCESS
;
3315 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
3317 const u8
*sta_addr
, *target_ap
;
3321 struct ft_rrb_frame
*frame
;
3327 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3328 * FT Request action frame body[variable]
3332 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
3333 "(len=%lu)", (unsigned long) len
);
3338 sta_addr
= data
+ 2;
3339 target_ap
= data
+ 8;
3343 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
3344 " Target AP=" MACSTR
" Action=%d)",
3345 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
3347 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
3348 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
3349 "STA=" MACSTR
" STA-Address=" MACSTR
,
3350 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
3355 * Do some sanity checking on the target AP address (not own and not
3356 * broadcast. This could be extended to filter based on a list of known
3357 * APs in the MD (if such a list were configured).
3359 if ((target_ap
[0] & 0x01) ||
3360 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
3361 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
3366 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
3368 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
3369 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
3373 /* RRB - Forward action frame to the target AP */
3374 frame
= os_malloc(sizeof(*frame
) + len
);
3377 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3378 frame
->packet_type
= FT_PACKET_REQUEST
;
3379 frame
->action_length
= host_to_le16(len
);
3380 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
3381 os_memcpy(frame
+ 1, data
, len
);
3383 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
3384 sizeof(*frame
) + len
);
3391 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
3392 u16 auth_transaction
, u16 resp
,
3393 const u8
*ies
, size_t ies_len
)
3395 struct wpa_state_machine
*sm
= ctx
;
3396 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
3398 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
3399 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
3403 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
3404 const u8
*current_ap
, const u8
*sta_addr
,
3405 const u8
*body
, size_t len
)
3407 struct wpa_state_machine
*sm
;
3410 size_t resp_ies_len
;
3413 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
3415 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
3420 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
3422 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
3423 sm
->ft_pending_cb_ctx
= sm
;
3424 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
3425 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3426 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
3429 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
3434 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
3435 resp_ies
, resp_ies_len
);
3441 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
3442 const u8
*current_ap
, const u8
*sta_addr
,
3443 u16 status
, const u8
*resp_ies
,
3444 size_t resp_ies_len
)
3446 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
3448 struct ft_rrb_frame
*frame
;
3451 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
3452 " CurrentAP=" MACSTR
" status=%d",
3453 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
3454 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3456 /* RRB - Forward action frame response to the Current AP */
3459 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3460 * Status_Code[2] FT Request action frame body[variable]
3462 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
3464 frame
= os_malloc(sizeof(*frame
) + rlen
);
3467 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3468 frame
->packet_type
= FT_PACKET_RESPONSE
;
3469 frame
->action_length
= host_to_le16(rlen
);
3470 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
3471 pos
= (u8
*) (frame
+ 1);
3472 *pos
++ = WLAN_ACTION_FT
;
3473 *pos
++ = 2; /* Action: Response */
3474 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
3476 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
3478 WPA_PUT_LE16(pos
, status
);
3481 os_memcpy(pos
, resp_ies
, resp_ies_len
);
3483 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
3484 sizeof(*frame
) + rlen
);
3491 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
3492 const struct tlv_list
*tlvs
,
3493 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3494 const u8
*r1kh_id
, const u8
*s1kh_id
,
3495 const struct tlv_list
*tlv_auth
,
3496 const u8
*src_addr
, u8 type
,
3497 u8
**packet
, size_t *packet_len
)
3499 u8 pmk_r1
[PMK_LEN_MAX
];
3500 size_t pmk_r1_len
= pmk_r0
->pmk_r0_len
;
3501 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3502 u8 f_pairwise
[sizeof(le16
)];
3503 u8 f_expires_in
[sizeof(le16
)];
3504 u8 f_session_timeout
[sizeof(le32
)];
3506 int session_timeout
;
3507 struct os_reltime now
;
3509 struct tlv_list sess_tlv
[] = {
3510 { .type
= FT_RRB_PMK_R1
, .len
= pmk_r1_len
,
3512 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3513 .data
= pmk_r1_name
},
3514 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3515 .data
= f_pairwise
},
3516 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3517 .data
= f_expires_in
},
3518 { .type
= FT_RRB_IDENTITY
, .len
= pmk_r0
->identity_len
,
3519 .data
= pmk_r0
->identity
},
3520 { .type
= FT_RRB_RADIUS_CUI
, .len
= pmk_r0
->radius_cui_len
,
3521 .data
= pmk_r0
->radius_cui
},
3522 { .type
= FT_RRB_SESSION_TIMEOUT
,
3523 .len
= sizeof(f_session_timeout
),
3524 .data
= f_session_timeout
},
3525 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3528 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_len
,
3529 pmk_r0
->pmk_r0_name
, r1kh_id
,
3530 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3532 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1 (for peer AP)",
3533 pmk_r1
, pmk_r1_len
);
3534 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name (for peer AP)",
3535 pmk_r1_name
, WPA_PMK_NAME_LEN
);
3536 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3538 os_get_reltime(&now
);
3539 if (pmk_r0
->expiration
> now
.sec
)
3540 expires_in
= pmk_r0
->expiration
- now
.sec
;
3541 else if (pmk_r0
->expiration
)
3545 WPA_PUT_LE16(f_expires_in
, expires_in
);
3547 if (pmk_r0
->session_timeout
> now
.sec
)
3548 session_timeout
= pmk_r0
->session_timeout
- now
.sec
;
3549 else if (pmk_r0
->session_timeout
)
3550 session_timeout
= 1;
3552 session_timeout
= 0;
3553 WPA_PUT_LE32(f_session_timeout
, session_timeout
);
3555 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3556 pmk_r0
->vlan
, src_addr
, type
,
3557 packet
, packet_len
);
3559 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
3565 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3567 const u8
*enc
, size_t enc_len
,
3568 const u8
*auth
, size_t auth_len
,
3571 const char *msgtype
= "pull request";
3572 u8
*plain
= NULL
, *packet
= NULL
;
3573 size_t plain_len
= 0, packet_len
= 0;
3574 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3578 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3579 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3580 size_t f_pmk_r0_name_len
;
3581 const struct wpa_ft_pmk_r0_sa
*r0
;
3583 struct tlv_list resp
[2];
3584 struct tlv_list resp_auth
[5];
3585 struct ft_rrb_seq f_seq
;
3587 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3589 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3590 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3592 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3593 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3597 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3598 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3600 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3603 key_len
= sizeof(r1kh
->key
);
3604 } else if (r1kh_wildcard
) {
3605 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3606 key
= r1kh_wildcard
->key
;
3607 key_len
= sizeof(r1kh_wildcard
->key
);
3612 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3613 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3615 seq_ret
= FT_RRB_SEQ_DROP
;
3617 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3618 auth
, auth_len
, msgtype
, no_defer
);
3619 if (!no_defer
&& r1kh_wildcard
&&
3620 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3621 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3622 seq_ret
= FT_RRB_SEQ_DEFER
;
3625 if (seq_ret
== FT_RRB_SEQ_DROP
)
3628 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3629 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3630 &plain
, &plain_len
) < 0)
3634 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3636 wpa_auth
->conf
.rkh_pos_timeout
);
3640 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3641 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3642 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3643 enc
, enc_len
, auth
, auth_len
,
3644 &wpa_ft_rrb_rx_pull
);
3648 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3650 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3651 wpa_auth
->conf
.rkh_pos_timeout
);
3653 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3654 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3657 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3658 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3660 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3661 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3665 resp
[0].type
= FT_RRB_S1KH_ID
;
3666 resp
[0].len
= f_s1kh_id_len
;
3667 resp
[0].data
= f_s1kh_id
;
3668 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3670 resp
[1].data
= NULL
;
3672 resp_auth
[0].type
= FT_RRB_NONCE
;
3673 resp_auth
[0].len
= f_nonce_len
;
3674 resp_auth
[0].data
= f_nonce
;
3675 resp_auth
[1].type
= FT_RRB_SEQ
;
3676 resp_auth
[1].len
= sizeof(f_seq
);
3677 resp_auth
[1].data
= (u8
*) &f_seq
;
3678 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3679 resp_auth
[2].len
= f_r0kh_id_len
;
3680 resp_auth
[2].data
= f_r0kh_id
;
3681 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3682 resp_auth
[3].len
= f_r1kh_id_len
;
3683 resp_auth
[3].data
= f_r1kh_id
;
3684 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3685 resp_auth
[4].len
= 0;
3686 resp_auth
[4].data
= NULL
;
3688 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0) {
3689 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3690 ret
= wpa_ft_rrb_build(key
, key_len
, resp
, NULL
, resp_auth
,
3691 NULL
, wpa_auth
->addr
,
3692 FT_PACKET_R0KH_R1KH_RESP
,
3693 &packet
, &packet_len
);
3695 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
,
3696 f_s1kh_id
, resp_auth
, wpa_auth
->addr
,
3697 FT_PACKET_R0KH_R1KH_RESP
,
3698 &packet
, &packet_len
);
3702 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3703 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3714 /* @returns 0 on success
3716 * -2 if FR_RRB_PAIRWISE is missing
3718 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3719 const u8
*src_addr
, u8 type
,
3720 const u8
*enc
, size_t enc_len
,
3721 const u8
*auth
, size_t auth_len
,
3722 const char *msgtype
, u8
*s1kh_id_out
,
3723 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3725 const u8
*enc
, size_t enc_len
,
3726 const u8
*auth
, size_t auth_len
,
3730 size_t plain_len
= 0;
3731 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3735 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3736 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3737 const u8
*f_expires_in
;
3738 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3739 const u8
*f_identity
, *f_radius_cui
;
3740 const u8
*f_session_timeout
;
3741 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3742 size_t f_expires_in_len
;
3743 size_t f_identity_len
, f_radius_cui_len
;
3744 size_t f_session_timeout_len
;
3748 int session_timeout
;
3749 struct vlan_description vlan
;
3752 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3753 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3755 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3756 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3758 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3759 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3763 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3767 key_len
= sizeof(r0kh
->key
);
3768 } else if (r0kh_wildcard
) {
3769 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3770 key
= r0kh_wildcard
->key
;
3771 key_len
= sizeof(r0kh_wildcard
->key
);
3776 seq_ret
= FT_RRB_SEQ_DROP
;
3778 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3779 auth
, auth_len
, msgtype
,
3782 if (cb
&& r0kh_wildcard
&&
3783 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3784 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3785 seq_ret
= FT_RRB_SEQ_DEFER
;
3788 if (seq_ret
== FT_RRB_SEQ_DROP
)
3791 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3792 src_addr
, type
, &plain
, &plain_len
) < 0)
3796 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3797 f_r0kh_id
, f_r0kh_id_len
,
3798 wpa_auth
->conf
.rkh_pos_timeout
);
3802 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3803 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3804 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3805 enc
, enc_len
, auth
, auth_len
, cb
);
3809 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3811 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3812 wpa_auth
->conf
.rkh_pos_timeout
);
3814 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3815 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3818 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3821 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3822 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3825 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3826 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3827 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
3829 pmk_r1_len
= PMK_LEN
;
3830 if (wpa_ft_rrb_get_tlv(plain
, plain_len
, FT_RRB_PMK_R1
, &f_pmk_r1_len
,
3832 (f_pmk_r1_len
== PMK_LEN
|| f_pmk_r1_len
== SHA384_MAC_LEN
))
3833 pmk_r1_len
= f_pmk_r1_len
;
3834 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, pmk_r1_len
);
3835 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, pmk_r1_len
);
3837 pairwise
= WPA_GET_LE16(f_pairwise
);
3839 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
3842 expires_in
= WPA_GET_LE16(f_expires_in
);
3846 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
3849 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
3850 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
3851 wpa_ft_rrb_dump(plain
, plain_len
);
3855 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
3856 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
3858 RRB_GET_OPTIONAL(FT_RRB_IDENTITY
, identity
, msgtype
, -1);
3860 wpa_hexdump_ascii(MSG_DEBUG
, "FT: Identity", f_identity
,
3863 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI
, radius_cui
, msgtype
, -1);
3865 wpa_hexdump_ascii(MSG_DEBUG
, "FT: CUI", f_radius_cui
,
3868 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT
, session_timeout
, msgtype
,
3870 if (f_session_timeout
)
3871 session_timeout
= WPA_GET_LE32(f_session_timeout
);
3873 session_timeout
= 0;
3874 wpa_printf(MSG_DEBUG
, "FT: session_timeout %d", session_timeout
);
3876 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, pmk_r1_len
,
3878 pairwise
, &vlan
, expires_in
, session_timeout
,
3879 f_identity
, f_identity_len
, f_radius_cui
,
3880 f_radius_cui_len
) < 0)
3886 os_memset(plain
, 0, plain_len
);
3895 static void ft_finish_pull(struct wpa_state_machine
*sm
)
3899 size_t resp_ies_len
;
3902 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
3905 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
3906 wpabuf_len(sm
->ft_pending_req_ies
),
3907 &resp_ies
, &resp_ies_len
);
3909 /* this loop is broken by ft_pending_pull_left_retries */
3910 wpa_printf(MSG_DEBUG
,
3911 "FT: Callback postponed until response is available");
3914 wpabuf_free(sm
->ft_pending_req_ies
);
3915 sm
->ft_pending_req_ies
= NULL
;
3917 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
3918 " - status %u", MAC2STR(sm
->addr
), status
);
3920 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
3921 sm
->ft_pending_auth_transaction
+ 1, status
,
3922 resp_ies
, resp_ies_len
);
3927 struct ft_get_sta_ctx
{
3930 struct wpa_state_machine
*sm
;
3934 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3936 struct ft_get_sta_ctx
*info
= ctx
;
3938 if ((info
->s1kh_id
&&
3939 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3940 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3941 FT_RRB_NONCE_LEN
) != 0 ||
3942 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3951 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3953 const u8
*enc
, size_t enc_len
,
3954 const u8
*auth
, size_t auth_len
,
3957 const char *msgtype
= "pull response";
3959 struct ft_get_sta_ctx ctx
;
3960 u8 s1kh_id
[ETH_ALEN
];
3964 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3966 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3967 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3969 os_memset(&ctx
, 0, sizeof(ctx
));
3970 ctx
.nonce
= f_nonce
;
3971 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3972 /* nonce not found */
3973 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3977 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3978 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3979 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3989 ctx
.s1kh_id
= s1kh_id
;
3990 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3991 wpa_printf(MSG_DEBUG
,
3992 "FT: Response to a pending pull request for " MACSTR
,
3993 MAC2STR(ctx
.sm
->addr
));
3994 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3996 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3997 ft_finish_pull(ctx
.sm
);
4005 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
4007 const u8
*enc
, size_t enc_len
,
4008 const u8
*auth
, size_t auth_len
, int no_defer
)
4010 const char *msgtype
= "push";
4012 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
4014 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4015 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
4016 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
4023 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
4024 const u8
*src_addr
, int type
,
4025 const u8
*enc
, size_t enc_len
,
4026 const u8
*auth
, size_t auth_len
,
4027 struct ft_remote_seq
**rkh_seq
,
4028 u8
**key
, size_t *key_len
,
4029 struct ft_remote_r0kh
**r0kh_out
,
4030 struct ft_remote_r1kh
**r1kh_out
,
4031 struct ft_remote_r0kh
**r0kh_wildcard_out
,
4032 struct ft_remote_r1kh
**r1kh_wildcard_out
)
4034 struct ft_remote_r0kh
*r0kh
= NULL
;
4035 struct ft_remote_r1kh
*r1kh
= NULL
;
4036 const u8
*f_r0kh_id
, *f_r1kh_id
;
4037 size_t f_r0kh_id_len
, f_r1kh_id_len
;
4038 int to_r0kh
, to_r1kh
;
4040 size_t plain_len
= 0;
4041 struct ft_remote_r0kh
*r0kh_wildcard
;
4042 struct ft_remote_r1kh
*r1kh_wildcard
;
4044 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4045 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4047 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
4048 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
4050 if (to_r0kh
&& to_r1kh
) {
4051 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
4055 if (!to_r0kh
&& !to_r1kh
) {
4056 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
4061 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
4062 &r0kh
, &r0kh_wildcard
);
4063 if (!r0kh_wildcard
&&
4064 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4065 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
4066 f_r0kh_id
, f_r0kh_id_len
);
4071 *key_len
= sizeof(r0kh
->key
);
4073 *key
= r0kh_wildcard
->key
;
4074 *key_len
= sizeof(r0kh_wildcard
->key
);
4079 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
4081 if (!r1kh_wildcard
&&
4082 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
4083 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
4084 f_r1kh_id
, FT_R1KH_ID_LEN
);
4089 *key_len
= sizeof(r1kh
->key
);
4091 *key
= r1kh_wildcard
->key
;
4092 *key_len
= sizeof(r1kh_wildcard
->key
);
4096 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
4097 src_addr
, type
, &plain
, &plain_len
) < 0)
4104 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
4105 src_addr
, f_r0kh_id
,
4111 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
4112 *rkh_seq
= r0kh
->seq
;
4115 if (r0kh_wildcard_out
)
4116 *r0kh_wildcard_out
= r0kh_wildcard
;
4121 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
4122 src_addr
, f_r1kh_id
,
4127 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
4128 *rkh_seq
= r1kh
->seq
;
4131 if (r1kh_wildcard_out
)
4132 *r1kh_wildcard_out
= r1kh_wildcard
;
4141 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
4143 const u8
*enc
, size_t enc_len
,
4144 const u8
*auth
, size_t auth_len
,
4148 struct ft_rrb_seq f_seq
;
4149 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
4150 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
4151 struct ft_remote_seq
*rkh_seq
= NULL
;
4152 u8
*packet
= NULL
, *key
= NULL
;
4153 size_t packet_len
= 0, key_len
= 0;
4154 struct tlv_list seq_resp_auth
[5];
4156 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
4158 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
4159 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4160 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
4163 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
4164 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
4166 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4167 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4169 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
4170 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4174 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
4175 seq_resp_auth
[0].len
= f_nonce_len
;
4176 seq_resp_auth
[0].data
= f_nonce
;
4177 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
4178 seq_resp_auth
[1].len
= sizeof(f_seq
);
4179 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
4180 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
4181 seq_resp_auth
[2].len
= f_r0kh_id_len
;
4182 seq_resp_auth
[2].data
= f_r0kh_id
;
4183 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
4184 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
4185 seq_resp_auth
[3].data
= f_r1kh_id
;
4186 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
4187 seq_resp_auth
[4].len
= 0;
4188 seq_resp_auth
[4].data
= NULL
;
4190 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
4191 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4192 &packet
, &packet_len
) < 0)
4195 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
4196 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
4206 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
4208 const u8
*enc
, size_t enc_len
,
4209 const u8
*auth
, size_t auth_len
,
4214 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
4215 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
4216 const u8
*f_nonce
, *f_seq
;
4217 size_t f_nonce_len
, f_seq_len
;
4218 struct ft_remote_seq
*rkh_seq
= NULL
;
4219 struct ft_remote_item
*item
;
4220 struct os_reltime now
, now_remote
;
4222 const struct ft_rrb_seq
*msg_both
;
4223 u32 msg_dom
, msg_seq
;
4225 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
4227 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4228 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4229 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
4230 &r1kh_wildcard
) < 0)
4233 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
4234 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
4238 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
4240 if (os_memcmp_const(f_nonce
, item
->nonce
,
4241 FT_RRB_NONCE_LEN
) != 0 ||
4242 os_get_reltime(&now
) < 0 ||
4243 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
4250 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
4255 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
4256 wpa_auth
->conf
.rkh_pos_timeout
);
4258 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
4262 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
4263 wpa_auth
->conf
.rkh_pos_timeout
);
4265 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
4268 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
4269 auth_len
, "seq response", 1);
4270 if (seq_ret
== FT_RRB_SEQ_OK
) {
4271 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
4272 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
4273 auth_len
, "seq response");
4275 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
4277 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
4279 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
4281 msg_dom
= le_to_host32(msg_both
->dom
);
4282 msg_seq
= le_to_host32(msg_both
->seq
);
4283 now_remote
.sec
= le_to_host32(msg_both
->ts
);
4284 now_remote
.usec
= 0;
4286 rkh_seq
->rx
.num_last
= 2;
4287 rkh_seq
->rx
.dom
= msg_dom
;
4288 rkh_seq
->rx
.offsetidx
= 0;
4289 /* Accept some older, possibly cached packets as well */
4290 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
4291 dl_list_len(&rkh_seq
->rx
.queue
);
4292 rkh_seq
->rx
.last
[1] = msg_seq
;
4294 /* local time - offset = remote time
4295 * <=> local time - remote time = offset */
4296 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
4299 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
4307 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4308 const u8
*data
, size_t data_len
)
4310 struct ft_rrb_frame
*frame
;
4312 const u8
*pos
, *end
, *start
;
4314 const u8
*sta_addr
, *target_ap_addr
;
4316 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
4319 if (data_len
< sizeof(*frame
)) {
4320 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
4321 (unsigned long) data_len
);
4326 frame
= (struct ft_rrb_frame
*) pos
;
4327 pos
+= sizeof(*frame
);
4329 alen
= le_to_host16(frame
->action_length
);
4330 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
4331 "action_length=%d ap_address=" MACSTR
,
4332 frame
->frame_type
, frame
->packet_type
, alen
,
4333 MAC2STR(frame
->ap_address
));
4335 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
4336 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
4337 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
4338 "unrecognized type %d", frame
->frame_type
);
4342 if (alen
> data_len
- sizeof(*frame
)) {
4343 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
4348 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
4350 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
4351 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
4352 "room for Action Frame body); alen=%lu",
4353 (unsigned long) alen
);
4359 if (*pos
!= WLAN_ACTION_FT
) {
4360 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
4369 target_ap_addr
= pos
;
4371 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
4372 MACSTR
" target_ap_addr=" MACSTR
,
4373 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
4375 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
4376 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
4379 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
4380 "RRB Request", action
);
4384 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
4385 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
4386 "RRB Request does not match with own "
4391 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
4392 sta_addr
, pos
, end
- pos
) < 0)
4394 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
4397 if (end
- pos
< 2) {
4398 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
4399 "code in RRB Response");
4402 status_code
= WPA_GET_LE16(pos
);
4405 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
4406 "(status_code=%d)", status_code
);
4408 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
4411 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
4412 "packet_type %d", frame
->packet_type
);
4417 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
4425 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4426 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
4429 const u8
*auth
, *enc
;
4433 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
4434 MACSTR
, MAC2STR(src_addr
));
4435 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
4436 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB frame payload", data
, data_len
);
4438 if (is_multicast_ether_addr(src_addr
)) {
4439 wpa_printf(MSG_DEBUG
,
4440 "FT: RRB-OUI received frame from multicast address "
4441 MACSTR
, MAC2STR(src_addr
));
4445 if (is_multicast_ether_addr(dst_addr
)) {
4446 wpa_printf(MSG_DEBUG
,
4447 "FT: RRB-OUI received frame from remote AP " MACSTR
4448 " to multicast address " MACSTR
,
4449 MAC2STR(src_addr
), MAC2STR(dst_addr
));
4453 if (data_len
< sizeof(u16
)) {
4454 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4458 alen
= WPA_GET_LE16(data
);
4459 if (data_len
< sizeof(u16
) + alen
) {
4460 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4464 auth
= data
+ sizeof(u16
);
4465 wpa_hexdump(MSG_MSGDUMP
, "FT: Authenticated payload", auth
, alen
);
4466 enc
= data
+ sizeof(u16
) + alen
;
4467 elen
= data_len
- sizeof(u16
) - alen
;
4468 wpa_hexdump(MSG_MSGDUMP
, "FT: Encrypted payload", enc
, elen
);
4470 switch (oui_suffix
) {
4471 case FT_PACKET_R0KH_R1KH_PULL
:
4472 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4475 case FT_PACKET_R0KH_R1KH_RESP
:
4476 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4479 case FT_PACKET_R0KH_R1KH_PUSH
:
4480 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4483 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
4484 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4487 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
4488 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
4495 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
4496 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
4497 struct ft_remote_r1kh
*r1kh
,
4502 struct ft_rrb_seq f_seq
;
4503 struct tlv_list push
[] = {
4504 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
4506 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
4507 .data
= pmk_r0
->pmk_r0_name
},
4508 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4510 struct tlv_list push_auth
[] = {
4511 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
4512 .data
= (u8
*) &f_seq
},
4513 { .type
= FT_RRB_R0KH_ID
,
4514 .len
= wpa_auth
->conf
.r0_key_holder_len
,
4515 .data
= wpa_auth
->conf
.r0_key_holder
},
4516 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
4518 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4521 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
4522 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4526 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
4527 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
4528 FT_PACKET_R0KH_R1KH_PUSH
,
4529 &packet
, &packet_len
) < 0)
4532 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4533 packet
, packet_len
);
4540 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
4542 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
4543 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
4544 struct ft_remote_r1kh
*r1kh
;
4546 if (!wpa_auth
->conf
.pmk_r1_push
)
4548 if (!wpa_auth
->conf
.r1kh_list
)
4551 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
4552 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4559 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4561 r0
->pmk_r1_pushed
= 1;
4563 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4564 "for STA " MACSTR
, MAC2STR(addr
));
4566 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4567 if (is_zero_ether_addr(r1kh
->addr
) ||
4568 is_zero_ether_addr(r1kh
->id
))
4570 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4572 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4576 #endif /* CONFIG_IEEE80211R_AP */