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 "crypto/aes.h"
17 #include "crypto/aes_siv.h"
18 #include "crypto/aes_wrap.h"
19 #include "crypto/sha384.h"
20 #include "crypto/random.h"
21 #include "ap_config.h"
22 #include "ieee802_11.h"
25 #include "wpa_auth_i.h"
28 #ifdef CONFIG_IEEE80211R_AP
30 const unsigned int ftRRBseqTimeout
= 10;
31 const unsigned int ftRRBmaxQueueLen
= 100;
34 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
35 const u8
*current_ap
, const u8
*sta_addr
,
36 u16 status
, const u8
*resp_ies
,
38 static void ft_finish_pull(struct wpa_state_machine
*sm
);
39 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
40 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
50 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
51 * @key: AES-SIV key for AEAD
52 * @key_len: Length of key in octets
53 * @enc: Pointer to encrypted TLVs
54 * @enc_len: Length of encrypted TLVs in octets
55 * @auth: Pointer to authenticated TLVs
56 * @auth_len: Length of authenticated TLVs in octets
57 * @src_addr: MAC address of the frame sender
58 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
59 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
60 * needs to be freed by the caller if not NULL;
61 * will only be returned on success
62 * @plain_len: Pointer to return the length of the allocated plaintext buffer
64 * Returns: 0 on success, -1 on error
66 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
67 const u8
*enc
, const size_t enc_len
,
68 const u8
*auth
, const size_t auth_len
,
69 const u8
*src_addr
, u8 type
,
70 u8
**plain
, size_t *plain_size
)
72 const u8
*ad
[3] = { src_addr
, auth
, &type
};
73 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
75 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
77 if (!key
) { /* skip decryption */
78 *plain
= os_memdup(enc
, enc_len
);
79 if (enc_len
> 0 && !*plain
)
82 *plain_size
= enc_len
;
90 if (enc_len
< AES_BLOCK_SIZE
)
93 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
97 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
101 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
102 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
103 *plain
, *plain_size
);
110 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
116 /* get first tlv record in packet matching type
117 * @data (decrypted) packet
118 * @return 0 on success else -1
120 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
121 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
123 const struct ft_rrb_tlv
*f
;
129 type16
= host_to_le16(type
);
131 while (left
>= sizeof(*f
)) {
132 f
= (const struct ft_rrb_tlv
*) plain
;
136 len
= le_to_host16(f
->len
);
139 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
143 if (f
->type
== type16
) {
157 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
159 const struct ft_rrb_tlv
*f
;
165 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
166 while (left
>= sizeof(*f
)) {
167 f
= (const struct ft_rrb_tlv
*) plain
;
171 len
= le_to_host16(f
->len
);
173 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
174 le_to_host16(f
->type
), len
);
177 wpa_printf(MSG_DEBUG
,
178 "FT: RRB message truncated: left %zu bytes, need %zu",
183 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
190 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
192 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
196 static int cmp_int(const void *a
, const void *b
)
206 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
207 struct vlan_description
*vlan
)
209 struct ft_rrb_tlv
*f
;
218 os_memset(vlan
, 0, sizeof(*vlan
));
220 while (left
>= sizeof(*f
)) {
221 f
= (struct ft_rrb_tlv
*) plain
;
226 len
= le_to_host16(f
->len
);
227 type
= le_to_host16(f
->type
);
230 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
234 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
237 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
238 wpa_printf(MSG_DEBUG
,
239 "FT: RRB VLAN_UNTAGGED invalid length");
243 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
244 wpa_printf(MSG_DEBUG
,
245 "FT: RRB VLAN_TAGGED invalid length");
249 while (len
>= sizeof(le16
)) {
250 vlan_id
= WPA_GET_LE16(plain
);
251 plain
+= sizeof(le16
);
252 left
-= sizeof(le16
);
255 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
256 wpa_printf(MSG_DEBUG
,
257 "FT: RRB VLAN ID invalid %d",
262 if (type
== FT_RRB_VLAN_UNTAGGED
)
263 vlan
->untagged
= vlan_id
;
265 if (type
== FT_RRB_VLAN_TAGGED
&&
266 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
267 vlan
->tagged
[taggedidx
] = vlan_id
;
269 } else if (type
== FT_RRB_VLAN_TAGGED
) {
270 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
280 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
282 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
288 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
296 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
297 tlv_len
+= sizeof(struct ft_rrb_tlv
);
298 tlv_len
+= tlvs
[i
].len
;
305 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
310 struct ft_rrb_tlv
*hdr
;
318 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
319 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
321 tlv_len
+= sizeof(*hdr
);
322 hdr
= (struct ft_rrb_tlv
*) pos
;
323 hdr
->type
= host_to_le16(tlvs
[i
].type
);
324 hdr
->len
= host_to_le16(tlvs
[i
].len
);
325 pos
= start
+ tlv_len
;
327 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
329 if (tlvs
[i
].len
== 0)
331 tlv_len
+= tlvs
[i
].len
;
332 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
333 pos
= start
+ tlv_len
;
340 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
345 if (!vlan
|| !vlan
->notempty
)
348 if (vlan
->untagged
) {
349 tlv_len
+= sizeof(struct ft_rrb_tlv
);
350 tlv_len
+= sizeof(le16
);
353 tlv_len
+= sizeof(struct ft_rrb_tlv
);
354 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
355 tlv_len
+= sizeof(le16
);
361 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
362 u8
*start
, u8
*endpos
)
366 struct ft_rrb_tlv
*hdr
;
369 if (!vlan
|| !vlan
->notempty
)
373 if (vlan
->untagged
) {
374 tlv_len
+= sizeof(*hdr
);
375 if (start
+ tlv_len
> endpos
)
377 hdr
= (struct ft_rrb_tlv
*) pos
;
378 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
379 hdr
->len
= host_to_le16(sizeof(le16
));
380 pos
= start
+ tlv_len
;
382 tlv_len
+= sizeof(le16
);
383 if (start
+ tlv_len
> endpos
)
385 WPA_PUT_LE16(pos
, vlan
->untagged
);
386 pos
= start
+ tlv_len
;
389 if (!vlan
->tagged
[0])
392 tlv_len
+= sizeof(*hdr
);
393 if (start
+ tlv_len
> endpos
)
395 hdr
= (struct ft_rrb_tlv
*) pos
;
396 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
397 len
= 0; /* len is computed below */
398 pos
= start
+ tlv_len
;
400 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
401 tlv_len
+= sizeof(le16
);
402 if (start
+ tlv_len
> endpos
)
405 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
406 pos
= start
+ tlv_len
;
409 hdr
->len
= host_to_le16(len
);
415 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
416 const struct tlv_list
*tlvs2
,
417 const struct vlan_description
*vlan
,
418 u8
**plain
, size_t *plain_len
)
423 tlv_len
= wpa_ft_tlv_len(tlvs1
);
424 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
425 tlv_len
+= wpa_ft_vlan_len(vlan
);
427 *plain_len
= tlv_len
;
428 *plain
= os_zalloc(tlv_len
);
430 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
435 endpos
= *plain
+ tlv_len
;
436 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
437 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
438 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
442 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
456 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
457 const u8
*plain
, const size_t plain_len
,
458 const u8
*auth
, const size_t auth_len
,
459 const u8
*src_addr
, u8 type
, u8
*enc
)
461 const u8
*ad
[3] = { src_addr
, auth
, &type
};
462 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
464 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
466 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
469 /* encryption not needed, return plaintext as packet */
470 os_memcpy(enc
, plain
, plain_len
);
471 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
472 3, ad
, ad_len
, enc
) < 0) {
473 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
482 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
483 * @key: AES-SIV key for AEAD
484 * @key_len: Length of key in octets
485 * @tlvs_enc0: First set of to-be-encrypted TLVs
486 * @tlvs_enc1: Second set of to-be-encrypted TLVs
487 * @tlvs_auth: Set of to-be-authenticated TLVs
488 * @src_addr: MAC address of the frame sender
489 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
490 * @packet Pointer to return the pointer to the allocated packet buffer;
491 * needs to be freed by the caller if not null;
492 * will only be returned on success
493 * @packet_len: Pointer to return the length of the allocated buffer in octets
494 * Returns: 0 on success, -1 on error
496 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
497 const struct tlv_list
*tlvs_enc0
,
498 const struct tlv_list
*tlvs_enc1
,
499 const struct tlv_list
*tlvs_auth
,
500 const struct vlan_description
*vlan
,
501 const u8
*src_addr
, u8 type
,
502 u8
**packet
, size_t *packet_len
)
504 u8
*plain
= NULL
, *auth
= NULL
, *pos
;
505 size_t plain_len
= 0, auth_len
= 0;
509 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
512 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
515 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
517 *packet_len
+= AES_BLOCK_SIZE
;
518 *packet
= os_zalloc(*packet_len
);
523 WPA_PUT_LE16(pos
, auth_len
);
525 os_memcpy(pos
, auth
, auth_len
);
527 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
528 auth_len
, src_addr
, type
, pos
) < 0)
534 bin_clear_free(plain
, plain_len
);
538 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
548 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
549 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
550 &f_##field##_len, &f_##field) < 0 || \
551 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
552 wpa_printf(MSG_INFO, "FT: Missing required " #field \
553 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
554 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
559 #define RRB_GET(type, field, txt, checklength) \
560 RRB_GET_SRC(plain, type, field, txt, checklength)
561 #define RRB_GET_AUTH(type, field, txt, checklength) \
562 RRB_GET_SRC(auth, type, field, txt, checklength)
564 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
565 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
566 &f_##field##_len, &f_##field) < 0 || \
567 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
568 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
569 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
570 f_##field##_len = 0; \
575 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
576 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
577 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
578 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
580 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
581 const u8
*data
, size_t data_len
)
583 if (wpa_auth
->cb
->send_ether
== NULL
)
585 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
586 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
591 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
592 const u8
*dst
, u8 oui_suffix
,
593 const u8
*data
, size_t data_len
)
595 if (!wpa_auth
->cb
->send_oui
)
597 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
,
598 oui_suffix
, MAC2STR(dst
));
599 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
604 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
605 const u8
*dst
, const u8
*data
, size_t data_len
)
607 if (wpa_auth
->cb
->send_ft_action
== NULL
)
609 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
614 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
615 const u8
*addr
, const u8
*p2p_dev_addr
,
618 if (wpa_auth
->cb
->get_psk
== NULL
)
620 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
625 static struct wpa_state_machine
*
626 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
628 if (wpa_auth
->cb
->add_sta
== NULL
)
630 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
634 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
635 const u8
*sta_addr
, struct vlan_description
*vlan
)
637 if (!wpa_auth
->cb
->set_vlan
)
639 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
643 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
644 const u8
*sta_addr
, struct vlan_description
*vlan
)
646 if (!wpa_auth
->cb
->get_vlan
)
648 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
653 wpa_ft_set_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
654 const u8
*identity
, size_t identity_len
)
656 if (!wpa_auth
->cb
->set_identity
)
658 return wpa_auth
->cb
->set_identity(wpa_auth
->cb_ctx
, sta_addr
, identity
,
664 wpa_ft_get_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
668 if (!wpa_auth
->cb
->get_identity
)
670 return wpa_auth
->cb
->get_identity(wpa_auth
->cb_ctx
, sta_addr
, buf
);
675 wpa_ft_set_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
676 const u8
*radius_cui
, size_t radius_cui_len
)
678 if (!wpa_auth
->cb
->set_radius_cui
)
680 return wpa_auth
->cb
->set_radius_cui(wpa_auth
->cb_ctx
, sta_addr
,
681 radius_cui
, radius_cui_len
);
686 wpa_ft_get_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
690 if (!wpa_auth
->cb
->get_radius_cui
)
692 return wpa_auth
->cb
->get_radius_cui(wpa_auth
->cb_ctx
, sta_addr
, buf
);
697 wpa_ft_set_session_timeout(struct wpa_authenticator
*wpa_auth
,
698 const u8
*sta_addr
, int session_timeout
)
700 if (!wpa_auth
->cb
->set_session_timeout
)
702 wpa_auth
->cb
->set_session_timeout(wpa_auth
->cb_ctx
, sta_addr
,
708 wpa_ft_get_session_timeout(struct wpa_authenticator
*wpa_auth
,
711 if (!wpa_auth
->cb
->get_session_timeout
)
713 return wpa_auth
->cb
->get_session_timeout(wpa_auth
->cb_ctx
, sta_addr
);
717 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
719 u8
*tspec_ie
, size_t tspec_ielen
)
721 if (wpa_auth
->cb
->add_tspec
== NULL
) {
722 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
725 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
730 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
734 if (len
< 2 + sizeof(struct rsn_mdie
))
737 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
738 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
739 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
740 pos
+= MOBILITY_DOMAIN_ID_LEN
;
742 if (conf
->ft_over_ds
)
743 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
750 int wpa_write_ftie(struct wpa_auth_config
*conf
, int use_sha384
,
751 const u8
*r0kh_id
, size_t r0kh_id_len
,
752 const u8
*anonce
, const u8
*snonce
,
753 u8
*buf
, size_t len
, const u8
*subelem
,
756 u8
*pos
= buf
, *ielen
;
757 size_t hdrlen
= use_sha384
? sizeof(struct rsn_ftie_sha384
) :
758 sizeof(struct rsn_ftie
);
760 if (len
< 2 + hdrlen
+ 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
764 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
768 struct rsn_ftie_sha384
*hdr
= (struct rsn_ftie_sha384
*) pos
;
770 os_memset(hdr
, 0, sizeof(*hdr
));
772 WPA_PUT_LE16(hdr
->mic_control
, 0);
774 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
776 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
778 struct rsn_ftie
*hdr
= (struct rsn_ftie
*) pos
;
780 os_memset(hdr
, 0, sizeof(*hdr
));
782 WPA_PUT_LE16(hdr
->mic_control
, 0);
784 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
786 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
789 /* Optional Parameters */
790 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
791 *pos
++ = FT_R1KH_ID_LEN
;
792 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
793 pos
+= FT_R1KH_ID_LEN
;
796 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
797 *pos
++ = r0kh_id_len
;
798 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
803 os_memcpy(pos
, subelem
, subelem_len
);
807 *ielen
= pos
- buf
- 2;
813 /* A packet to be handled after seq response */
814 struct ft_remote_item
{
817 u8 nonce
[FT_RRB_NONCE_LEN
];
818 struct os_reltime nonce_ts
;
820 u8 src_addr
[ETH_ALEN
];
825 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
827 const u8
*enc
, size_t enc_len
,
828 const u8
*auth
, size_t auth_len
,
833 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
835 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
836 dl_list_del(&item
->list
);
837 bin_clear_free(item
->enc
, item
->enc_len
);
843 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
844 struct ft_remote_seq
*rkh_seq
, int cb
)
846 struct ft_remote_item
*item
, *n
;
848 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
849 struct ft_remote_item
, list
) {
851 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
852 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
853 wpa_ft_rrb_seq_free(item
);
858 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
860 struct ft_remote_item
*item
= timeout_ctx
;
862 wpa_ft_rrb_seq_free(item
);
867 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
868 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
869 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
870 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
871 const u8
*enc
, size_t enc_len
,
872 const u8
*auth
, size_t auth_len
,
873 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
875 const u8
*enc
, size_t enc_len
,
876 const u8
*auth
, size_t auth_len
,
879 struct ft_remote_item
*item
= NULL
;
882 struct tlv_list seq_req_auth
[] = {
883 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
884 .data
= NULL
/* to be filled: item->nonce */ },
885 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
887 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
889 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
892 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
893 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
897 item
= os_zalloc(sizeof(*item
));
901 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
904 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
905 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
909 if (os_get_reltime(&item
->nonce_ts
) < 0)
912 if (enc
&& enc_len
> 0) {
913 item
->enc
= os_memdup(enc
, enc_len
);
914 item
->enc_len
= enc_len
;
919 if (auth
&& auth_len
> 0) {
920 item
->auth
= os_memdup(auth
, auth_len
);
921 item
->auth_len
= auth_len
;
926 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
929 seq_req_auth
[0].data
= item
->nonce
;
931 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
932 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
933 &packet
, &packet_len
) < 0) {
934 item
= NULL
; /* some other seq resp might still accept this */
938 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
940 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
947 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
950 bin_clear_free(item
->enc
, item
->enc_len
);
958 #define FT_RRB_SEQ_OK 0
959 #define FT_RRB_SEQ_DROP 1
960 #define FT_RRB_SEQ_DEFER 2
963 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
964 const u8
*enc
, size_t enc_len
,
965 const u8
*auth
, size_t auth_len
,
966 const char *msgtype
, int no_defer
)
970 const struct ft_rrb_seq
*msg_both
;
971 u32 msg_seq
, msg_off
, rkh_off
;
972 struct os_reltime now
;
975 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
976 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
977 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
979 if (rkh_seq
->rx
.num_last
== 0) {
980 /* first packet from remote */
984 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
985 /* remote might have rebooted */
989 if (os_get_reltime(&now
) == 0) {
990 u32 msg_ts_now_remote
, msg_ts_off
;
991 struct os_reltime now_remote
;
993 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
994 msg_ts_now_remote
= now_remote
.sec
;
995 msg_ts_off
= le_to_host32(msg_both
->ts
) -
996 (msg_ts_now_remote
- ftRRBseqTimeout
);
997 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
1001 msg_seq
= le_to_host32(msg_both
->seq
);
1002 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1003 msg_off
= msg_seq
- rkh_off
;
1004 if (msg_off
> 0xC0000000)
1005 goto out
; /* too old message, drop it */
1007 if (msg_off
<= 0x40000000) {
1008 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1009 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
1010 goto out
; /* duplicate message, drop it */
1013 return FT_RRB_SEQ_OK
;
1020 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
1021 MACSTR
, msgtype
, MAC2STR(src_addr
));
1023 return FT_RRB_SEQ_DEFER
;
1025 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
1026 msgtype
, MAC2STR(src_addr
));
1028 return FT_RRB_SEQ_DROP
;
1033 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
1034 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1035 const u8
*auth
, size_t auth_len
,
1036 const char *msgtype
)
1040 const struct ft_rrb_seq
*msg_both
;
1041 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
1045 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1046 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1048 msg_seq
= le_to_host32(msg_both
->seq
);
1050 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
1051 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
1052 rkh_seq
->rx
.num_last
++;
1056 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1057 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1058 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
1059 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
1060 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
1063 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
1064 rkh_seq
->rx
.offsetidx
= minidx
;
1068 /* RRB_GET_AUTH should never fail here as
1069 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1070 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
1074 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
1075 struct ft_rrb_seq
*f_seq
)
1077 struct os_reltime now
;
1079 if (os_get_reltime(&now
) < 0)
1082 if (!rkh_seq
->tx
.dom
) {
1083 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1084 sizeof(rkh_seq
->tx
.seq
))) {
1085 wpa_printf(MSG_ERROR
,
1086 "FT: Failed to get random data for sequence number initialization");
1087 rkh_seq
->tx
.seq
= now
.usec
;
1089 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1090 sizeof(rkh_seq
->tx
.dom
))) {
1091 wpa_printf(MSG_ERROR
,
1092 "FT: Failed to get random data for sequence number initialization");
1093 rkh_seq
->tx
.dom
= now
.usec
;
1095 rkh_seq
->tx
.dom
|= 1;
1098 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1099 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1100 f_seq
->ts
= host_to_le32(now
.sec
);
1108 struct wpa_ft_pmk_r0_sa
{
1109 struct dl_list list
;
1110 u8 pmk_r0
[PMK_LEN_MAX
];
1112 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1114 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1115 struct vlan_description
*vlan
;
1116 os_time_t expiration
; /* 0 for no expiration */
1118 size_t identity_len
;
1120 size_t radius_cui_len
;
1121 os_time_t session_timeout
; /* 0 for no expiration */
1122 /* TODO: radius_class, EAP type */
1126 struct wpa_ft_pmk_r1_sa
{
1127 struct dl_list list
;
1128 u8 pmk_r1
[PMK_LEN_MAX
];
1130 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1132 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1133 struct vlan_description
*vlan
;
1135 size_t identity_len
;
1137 size_t radius_cui_len
;
1138 os_time_t session_timeout
; /* 0 for no expiration */
1139 /* TODO: radius_class, EAP type */
1142 struct wpa_ft_pmk_cache
{
1143 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1144 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1148 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1149 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1152 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1157 dl_list_del(&r0
->list
);
1158 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1160 os_memset(r0
->pmk_r0
, 0, PMK_LEN_MAX
);
1162 os_free(r0
->identity
);
1163 os_free(r0
->radius_cui
);
1168 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1170 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1171 struct os_reltime now
;
1173 int session_timeout
;
1175 os_get_reltime(&now
);
1180 expires_in
= r0
->expiration
- now
.sec
;
1181 session_timeout
= r0
->session_timeout
- now
.sec
;
1182 /* conditions to remove from cache:
1183 * a) r0->expiration is set and hit
1185 * b) r0->session_timeout is set and hit
1187 if ((!r0
->expiration
|| expires_in
> 0) &&
1188 (!r0
->session_timeout
|| session_timeout
> 0)) {
1189 wpa_printf(MSG_ERROR
,
1190 "FT: %s() called for non-expired entry %p",
1192 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1193 if (r0
->expiration
&& expires_in
> 0)
1194 eloop_register_timeout(expires_in
+ 1, 0,
1195 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1196 if (r0
->session_timeout
&& session_timeout
> 0)
1197 eloop_register_timeout(session_timeout
+ 1, 0,
1198 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1202 wpa_ft_free_pmk_r0(r0
);
1206 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1211 dl_list_del(&r1
->list
);
1212 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1214 os_memset(r1
->pmk_r1
, 0, PMK_LEN_MAX
);
1216 os_free(r1
->identity
);
1217 os_free(r1
->radius_cui
);
1222 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1224 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1226 wpa_ft_free_pmk_r1(r1
);
1230 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1232 struct wpa_ft_pmk_cache
*cache
;
1234 cache
= os_zalloc(sizeof(*cache
));
1236 dl_list_init(&cache
->pmk_r0
);
1237 dl_list_init(&cache
->pmk_r1
);
1244 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1246 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1247 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1249 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1250 struct wpa_ft_pmk_r0_sa
, list
)
1251 wpa_ft_free_pmk_r0(r0
);
1253 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1254 struct wpa_ft_pmk_r1_sa
, list
)
1255 wpa_ft_free_pmk_r1(r1
);
1261 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1262 const u8
*spa
, const u8
*pmk_r0
,
1264 const u8
*pmk_r0_name
, int pairwise
,
1265 const struct vlan_description
*vlan
,
1266 int expires_in
, int session_timeout
,
1267 const u8
*identity
, size_t identity_len
,
1268 const u8
*radius_cui
, size_t radius_cui_len
)
1270 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1271 struct wpa_ft_pmk_r0_sa
*r0
;
1272 struct os_reltime now
;
1274 /* TODO: add limit on number of entries in cache */
1275 os_get_reltime(&now
);
1277 r0
= os_zalloc(sizeof(*r0
));
1281 os_memcpy(r0
->pmk_r0
, pmk_r0
, pmk_r0_len
);
1282 r0
->pmk_r0_len
= pmk_r0_len
;
1283 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1284 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1285 r0
->pairwise
= pairwise
;
1287 r0
->expiration
= now
.sec
+ expires_in
;
1288 if (vlan
&& vlan
->notempty
) {
1289 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1291 bin_clear_free(r0
, sizeof(*r0
));
1297 r0
->identity
= os_malloc(identity_len
);
1299 os_memcpy(r0
->identity
, identity
, identity_len
);
1300 r0
->identity_len
= identity_len
;
1304 r0
->radius_cui
= os_malloc(radius_cui_len
);
1305 if (r0
->radius_cui
) {
1306 os_memcpy(r0
->radius_cui
, radius_cui
, radius_cui_len
);
1307 r0
->radius_cui_len
= radius_cui_len
;
1310 if (session_timeout
> 0)
1311 r0
->session_timeout
= now
.sec
+ session_timeout
;
1313 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1315 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1317 if (session_timeout
> 0)
1318 eloop_register_timeout(session_timeout
+ 1, 0,
1319 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1325 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1326 const u8
*spa
, const u8
*pmk_r0_name
,
1327 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1329 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1330 struct wpa_ft_pmk_r0_sa
*r0
;
1331 struct os_reltime now
;
1333 os_get_reltime(&now
);
1334 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1335 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1336 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1337 WPA_PMK_NAME_LEN
) == 0) {
1348 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1349 const u8
*spa
, const u8
*pmk_r1
,
1351 const u8
*pmk_r1_name
, int pairwise
,
1352 const struct vlan_description
*vlan
,
1353 int expires_in
, int session_timeout
,
1354 const u8
*identity
, size_t identity_len
,
1355 const u8
*radius_cui
, size_t radius_cui_len
)
1357 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1358 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1359 struct wpa_ft_pmk_r1_sa
*r1
;
1360 struct os_reltime now
;
1362 /* TODO: limit on number of entries in cache */
1363 os_get_reltime(&now
);
1365 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1366 expires_in
= max_expires_in
;
1368 r1
= os_zalloc(sizeof(*r1
));
1372 os_memcpy(r1
->pmk_r1
, pmk_r1
, pmk_r1_len
);
1373 r1
->pmk_r1_len
= pmk_r1_len
;
1374 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1375 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1376 r1
->pairwise
= pairwise
;
1377 if (vlan
&& vlan
->notempty
) {
1378 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1380 bin_clear_free(r1
, sizeof(*r1
));
1386 r1
->identity
= os_malloc(identity_len
);
1388 os_memcpy(r1
->identity
, identity
, identity_len
);
1389 r1
->identity_len
= identity_len
;
1393 r1
->radius_cui
= os_malloc(radius_cui_len
);
1394 if (r1
->radius_cui
) {
1395 os_memcpy(r1
->radius_cui
, radius_cui
, radius_cui_len
);
1396 r1
->radius_cui_len
= radius_cui_len
;
1399 if (session_timeout
> 0)
1400 r1
->session_timeout
= now
.sec
+ session_timeout
;
1402 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1405 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1407 if (session_timeout
> 0)
1408 eloop_register_timeout(session_timeout
+ 1, 0,
1409 wpa_ft_expire_pmk_r1
, r1
, NULL
);
1415 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1416 const u8
*spa
, const u8
*pmk_r1_name
,
1417 u8
*pmk_r1
, size_t *pmk_r1_len
, int *pairwise
,
1418 struct vlan_description
*vlan
,
1419 const u8
**identity
, size_t *identity_len
,
1420 const u8
**radius_cui
, size_t *radius_cui_len
,
1421 int *session_timeout
)
1423 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1424 struct wpa_ft_pmk_r1_sa
*r1
;
1425 struct os_reltime now
;
1427 os_get_reltime(&now
);
1429 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1430 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1431 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1432 WPA_PMK_NAME_LEN
) == 0) {
1433 os_memcpy(pmk_r1
, r1
->pmk_r1
, r1
->pmk_r1_len
);
1434 *pmk_r1_len
= r1
->pmk_r1_len
;
1436 *pairwise
= r1
->pairwise
;
1437 if (vlan
&& r1
->vlan
)
1439 if (vlan
&& !r1
->vlan
)
1440 os_memset(vlan
, 0, sizeof(*vlan
));
1441 if (identity
&& identity_len
) {
1442 *identity
= r1
->identity
;
1443 *identity_len
= r1
->identity_len
;
1445 if (radius_cui
&& radius_cui_len
) {
1446 *radius_cui
= r1
->radius_cui
;
1447 *radius_cui_len
= r1
->radius_cui_len
;
1449 if (session_timeout
&& r1
->session_timeout
> now
.sec
)
1450 *session_timeout
= r1
->session_timeout
-
1452 else if (session_timeout
&& r1
->session_timeout
)
1453 *session_timeout
= 1;
1455 *session_timeout
= 0;
1464 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1469 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1471 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1475 dl_list_init(&r0kh
->seq
->rx
.queue
);
1481 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1482 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1483 struct ft_remote_r0kh
**r0kh_out
,
1484 struct ft_remote_r0kh
**r0kh_wildcard
)
1486 struct ft_remote_r0kh
*r0kh
;
1488 *r0kh_wildcard
= NULL
;
1491 if (wpa_auth
->conf
.r0kh_list
)
1492 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1495 for (; r0kh
; r0kh
= r0kh
->next
) {
1496 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1497 *r0kh_wildcard
= r0kh
;
1498 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1499 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1503 if (!*r0kh_out
&& !*r0kh_wildcard
)
1504 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1506 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1511 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1516 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1518 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1522 dl_list_init(&r1kh
->seq
->rx
.queue
);
1528 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1529 const u8
*f_r1kh_id
,
1530 struct ft_remote_r1kh
**r1kh_out
,
1531 struct ft_remote_r1kh
**r1kh_wildcard
)
1533 struct ft_remote_r1kh
*r1kh
;
1535 *r1kh_wildcard
= NULL
;
1538 if (wpa_auth
->conf
.r1kh_list
)
1539 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1542 for (; r1kh
; r1kh
= r1kh
->next
) {
1543 if (is_zero_ether_addr(r1kh
->addr
) &&
1544 is_zero_ether_addr(r1kh
->id
))
1545 *r1kh_wildcard
= r1kh
;
1547 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1551 if (!*r1kh_out
&& !*r1kh_wildcard
)
1552 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1554 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1559 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1560 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1562 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1563 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1564 f_r0kh_id_len
) != 0)
1571 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1572 const u8
*f_r1kh_id
)
1574 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1575 FT_R1KH_ID_LEN
) != 0)
1582 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1584 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1585 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1587 if (!wpa_auth
->conf
.r0kh_list
)
1590 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1591 if (r0kh
== timeout_ctx
)
1598 prev
->next
= r0kh
->next
;
1600 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1602 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1608 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1609 struct ft_remote_r0kh
*r0kh
, int timeout
)
1612 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1617 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1618 struct ft_remote_r0kh
*r0kh
, int timeout
)
1620 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1623 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1628 static struct ft_remote_r0kh
*
1629 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1630 struct ft_remote_r0kh
*r0kh_wildcard
,
1631 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1634 struct ft_remote_r0kh
*r0kh
;
1636 if (!wpa_auth
->conf
.r0kh_list
)
1639 r0kh
= os_zalloc(sizeof(*r0kh
));
1644 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1646 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1647 id_len
= FT_R0KH_ID_MAX_LEN
;
1648 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1649 r0kh
->id_len
= id_len
;
1651 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1653 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1654 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1657 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1660 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1667 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1669 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1670 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1672 if (!wpa_auth
->conf
.r1kh_list
)
1675 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1676 if (r1kh
== timeout_ctx
)
1683 prev
->next
= r1kh
->next
;
1685 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1687 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1693 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1694 struct ft_remote_r1kh
*r1kh
, int timeout
)
1697 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1702 static struct ft_remote_r1kh
*
1703 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1704 struct ft_remote_r1kh
*r1kh_wildcard
,
1705 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1707 struct ft_remote_r1kh
*r1kh
;
1709 if (!wpa_auth
->conf
.r1kh_list
)
1712 r1kh
= os_zalloc(sizeof(*r1kh
));
1716 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1717 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1718 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1719 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1720 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1723 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1726 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1733 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1735 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1739 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1741 struct ft_remote_r0kh
*r0kh
;
1742 struct ft_remote_r1kh
*r1kh
;
1744 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1746 if (wpa_auth
->conf
.r0kh_list
)
1747 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1750 for (; r0kh
; r0kh
= r0kh
->next
) {
1753 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1758 if (wpa_auth
->conf
.r1kh_list
)
1759 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1762 for (; r1kh
; r1kh
= r1kh
->next
) {
1765 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1772 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1774 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1775 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1777 if (wpa_auth
->conf
.r0kh_list
)
1778 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1782 r0kh_next
= r0kh
->next
;
1783 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1786 r0kh_prev
->next
= r0kh_next
;
1788 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1796 if (wpa_auth
->conf
.r1kh_list
)
1797 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1801 r1kh_next
= r1kh
->next
;
1802 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1805 r1kh_prev
->next
= r1kh_next
;
1807 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1817 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1819 wpa_ft_deinit_seq(wpa_auth
);
1820 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1824 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1825 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1827 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1829 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1832 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1833 &r0kh
, &r0kh_wildcard
);
1835 if (!r0kh_wildcard
) {
1836 /* r0kh removed after neg_timeout and might need re-adding */
1840 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1841 f_r0kh_id
, f_r0kh_id_len
);
1844 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1845 wpa_auth
->conf
.rkh_neg_timeout
);
1846 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1848 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1850 wpa_auth
->conf
.rkh_neg_timeout
);
1854 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1856 struct wpa_state_machine
*sm
= eloop_ctx
;
1858 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1860 if (sm
->ft_pending_pull_left_retries
<= 0)
1861 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1863 /* cancel multiple timeouts */
1864 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1869 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1870 const u8
*ies
, size_t ies_len
,
1871 const u8
*pmk_r0_name
)
1873 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1875 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1876 size_t packet_len
, key_len
;
1877 struct ft_rrb_seq f_seq
;
1878 int tsecs
, tusecs
, first
;
1879 struct wpabuf
*ft_pending_req_ies
;
1881 struct tlv_list req_enc
[] = {
1882 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1883 .data
= pmk_r0_name
},
1884 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1886 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1888 struct tlv_list req_auth
[] = {
1889 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1890 .data
= sm
->ft_pending_pull_nonce
},
1891 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1892 .data
= (u8
*) &f_seq
},
1893 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1894 .data
= sm
->r0kh_id
},
1895 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1896 .data
= f_r1kh_id
},
1897 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1900 if (sm
->ft_pending_pull_left_retries
<= 0)
1902 first
= sm
->ft_pending_pull_left_retries
==
1903 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1904 sm
->ft_pending_pull_left_retries
--;
1906 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1907 &r0kh
, &r0kh_wildcard
);
1909 /* Keep r0kh sufficiently long in the list for seq num check */
1910 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1911 1 + ftRRBseqTimeout
;
1913 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1914 } else if (r0kh_wildcard
) {
1915 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1916 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1917 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1918 r0kh_wildcard
->addr
,
1919 sm
->r0kh_id
, sm
->r0kh_id_len
,
1923 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1924 sm
->r0kh_id
, sm
->r0kh_id_len
);
1927 if (is_zero_ether_addr(r0kh
->addr
)) {
1928 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1929 sm
->r0kh_id
, sm
->r0kh_id_len
);
1932 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1933 wpa_printf(MSG_DEBUG
,
1934 "FT: R0KH-ID points to self - no matching key available");
1939 key_len
= sizeof(r0kh
->key
);
1941 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
1942 "address " MACSTR
, MAC2STR(r0kh
->addr
));
1944 if (r0kh
->seq
->rx
.num_last
== 0) {
1945 /* A sequence request will be sent out anyway when pull
1946 * response is received. Send it out now to avoid one RTT. */
1947 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
1948 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
1949 key_len
, NULL
, 0, NULL
, 0, NULL
);
1953 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
1954 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
1959 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
1960 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
1964 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
1965 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1966 &packet
, &packet_len
) < 0)
1969 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
1970 wpabuf_free(sm
->ft_pending_req_ies
);
1971 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
1972 if (!sm
->ft_pending_req_ies
) {
1977 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
1978 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
1979 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
1981 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1982 packet
, packet_len
);
1990 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
1991 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
1993 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
1994 struct vlan_description vlan
;
1995 const u8
*identity
, *radius_cui
;
1996 size_t identity_len
, radius_cui_len
;
1997 int session_timeout
;
1998 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
1999 SHA384_MAC_LEN
: PMK_LEN
;
2001 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2002 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2007 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2008 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2010 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2012 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2013 pmk_r0_name
, sm
->pairwise
, &vlan
, expires_in
,
2014 session_timeout
, identity
, identity_len
,
2015 radius_cui
, radius_cui_len
);
2019 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, const u8
*pmk
,
2020 struct wpa_ptk
*ptk
)
2022 u8 pmk_r0
[PMK_LEN_MAX
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2023 size_t pmk_r0_len
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
) ?
2024 SHA384_MAC_LEN
: PMK_LEN
;
2025 size_t pmk_r1_len
= pmk_r0_len
;
2026 u8 pmk_r1
[PMK_LEN_MAX
];
2027 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2028 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
2029 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
2030 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
2031 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
2032 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
2033 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
2034 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
2035 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2036 struct vlan_description vlan
;
2037 const u8
*identity
, *radius_cui
;
2038 size_t identity_len
, radius_cui_len
;
2039 int session_timeout
;
2041 if (sm
->xxkey_len
== 0) {
2042 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
2047 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2048 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2053 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2054 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2056 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2058 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
2059 r0kh
, r0kh_len
, sm
->addr
,
2060 pmk_r0
, pmk_r0_name
,
2061 wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
)) < 0)
2063 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, pmk_r0_len
);
2064 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
2065 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2066 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_len
,
2068 sm
->pairwise
, &vlan
, expires_in
,
2069 session_timeout
, identity
, identity_len
,
2070 radius_cui
, radius_cui_len
);
2072 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_len
, pmk_r0_name
, r1kh
, sm
->addr
,
2073 pmk_r1
, sm
->pmk_r1_name
) < 0)
2075 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, pmk_r1_len
);
2076 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
2078 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2079 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
, pmk_r1_len
,
2080 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
2081 expires_in
, session_timeout
, identity
,
2082 identity_len
, radius_cui
, radius_cui_len
);
2084 return wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2085 sm
->addr
, sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
2086 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
2090 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
2091 const u8
*addr
, int idx
, u8
*seq
)
2093 if (wpa_auth
->cb
->get_seqnum
== NULL
)
2095 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
2099 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2102 struct wpa_group
*gsm
= sm
->group
;
2103 size_t subelem_len
, pad_len
;
2110 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2112 kek_len
= sm
->PTK
.kek2_len
;
2115 kek_len
= sm
->PTK
.kek_len
;
2118 key_len
= gsm
->GTK_len
;
2119 if (key_len
> sizeof(keybuf
))
2123 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2126 pad_len
= key_len
% 8;
2128 pad_len
= 8 - pad_len
;
2129 if (key_len
+ pad_len
< 16)
2131 if (pad_len
&& key_len
< sizeof(keybuf
)) {
2132 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
2133 os_memset(keybuf
+ key_len
, 0, pad_len
);
2134 keybuf
[key_len
] = 0xdd;
2138 key
= gsm
->GTK
[gsm
->GN
- 1];
2141 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
2144 subelem_len
= 13 + key_len
+ 8;
2145 subelem
= os_zalloc(subelem_len
);
2146 if (subelem
== NULL
)
2149 subelem
[0] = FTIE_SUBELEM_GTK
;
2150 subelem
[1] = 11 + key_len
+ 8;
2151 /* Key ID in B0-B1 of Key Info */
2152 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
2153 subelem
[4] = gsm
->GTK_len
;
2154 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
2155 if (aes_wrap(kek
, kek_len
, key_len
/ 8, key
, subelem
+ 13)) {
2156 wpa_printf(MSG_DEBUG
,
2157 "FT: GTK subelem encryption failed: kek_len=%d",
2168 #ifdef CONFIG_IEEE80211W
2169 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2172 struct wpa_group
*gsm
= sm
->group
;
2178 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2180 kek_len
= sm
->PTK
.kek2_len
;
2183 kek_len
= sm
->PTK
.kek_len
;
2186 igtk_len
= wpa_cipher_key_len(sm
->wpa_auth
->conf
.group_mgmt_cipher
);
2188 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2190 subelem_len
= 1 + 1 + 2 + 6 + 1 + igtk_len
+ 8;
2191 subelem
= os_zalloc(subelem_len
);
2192 if (subelem
== NULL
)
2196 *pos
++ = FTIE_SUBELEM_IGTK
;
2197 *pos
++ = subelem_len
- 2;
2198 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
2200 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
2203 if (aes_wrap(kek
, kek_len
, igtk_len
/ 8,
2204 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
2205 wpa_printf(MSG_DEBUG
,
2206 "FT: IGTK subelem encryption failed: kek_len=%d",
2215 #endif /* CONFIG_IEEE80211W */
2218 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
2219 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
2220 const u8
*ies
, size_t ies_len
)
2222 struct ieee802_11_elems parse
;
2223 struct rsn_rdie
*rdie
;
2225 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
2227 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
2230 if (end
- pos
< (int) sizeof(*rdie
)) {
2231 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
2235 *pos
++ = WLAN_EID_RIC_DATA
;
2236 *pos
++ = sizeof(*rdie
);
2237 rdie
= (struct rsn_rdie
*) pos
;
2239 rdie
->descr_count
= 0;
2240 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2241 pos
+= sizeof(*rdie
);
2243 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2245 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2247 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2251 if (parse
.wmm_tspec
) {
2252 struct wmm_tspec_element
*tspec
;
2254 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2255 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2256 "(%d)", (int) parse
.wmm_tspec_len
);
2258 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2261 if (end
- pos
< (int) sizeof(*tspec
)) {
2262 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2265 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2268 tspec
= (struct wmm_tspec_element
*) pos
;
2269 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2273 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2276 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2277 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2278 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2280 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2281 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2283 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2285 /* TSPEC accepted; include updated TSPEC in response */
2286 rdie
->descr_count
= 1;
2287 pos
+= sizeof(struct wmm_tspec_element
);
2291 #endif /* NEED_AP_MLME */
2293 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2296 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2297 sizeof(struct wmm_tspec_element
));
2300 rdie
->status_code
= host_to_le16(res
);
2302 /* TSPEC accepted; include updated TSPEC in
2304 rdie
->descr_count
= 1;
2305 pos
+= sizeof(struct wmm_tspec_element
);
2311 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2312 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2317 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2318 const u8
*ric
, size_t ric_len
)
2320 const u8
*rpos
, *start
;
2321 const struct rsn_rdie
*rdie
;
2323 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2326 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2327 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2328 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2330 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2331 rpos
+= 2 + rpos
[1];
2334 while (rpos
+ 2 <= ric
+ ric_len
&&
2335 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2336 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2338 rpos
+= 2 + rpos
[1];
2340 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2342 start
, rpos
- start
);
2349 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2350 size_t max_len
, int auth_alg
,
2351 const u8
*req_ies
, size_t req_ies_len
)
2353 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2354 u8
*fte_mic
, *elem_count
;
2355 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2357 struct wpa_auth_config
*conf
;
2358 struct wpa_ft_ies parse
;
2360 u8
*anonce
, *snonce
;
2368 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
2369 conf
= &sm
->wpa_auth
->conf
;
2371 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2374 end
= pos
+ max_len
;
2376 if (auth_alg
== WLAN_AUTH_FT
) {
2378 * RSN (only present if this is a Reassociation Response and
2379 * part of a fast BSS transition)
2381 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2389 /* Mobility Domain Information */
2390 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2397 /* Fast BSS Transition Information */
2398 if (auth_alg
== WLAN_AUTH_FT
) {
2399 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2401 wpa_printf(MSG_DEBUG
,
2402 "FT: Failed to add GTK subelement");
2405 r0kh_id
= sm
->r0kh_id
;
2406 r0kh_id_len
= sm
->r0kh_id_len
;
2407 anonce
= sm
->ANonce
;
2408 snonce
= sm
->SNonce
;
2409 #ifdef CONFIG_IEEE80211W
2410 if (sm
->mgmt_frame_prot
) {
2414 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2416 wpa_printf(MSG_DEBUG
,
2417 "FT: Failed to add IGTK subelement");
2421 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2428 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2429 subelem_len
+= igtk_len
;
2432 #endif /* CONFIG_IEEE80211W */
2434 r0kh_id
= conf
->r0_key_holder
;
2435 r0kh_id_len
= conf
->r0_key_holder_len
;
2439 res
= wpa_write_ftie(conf
, use_sha384
, r0kh_id
, r0kh_id_len
,
2440 anonce
, snonce
, pos
, end
- pos
,
2441 subelem
, subelem_len
);
2450 struct rsn_ftie_sha384
*_ftie
=
2451 (struct rsn_ftie_sha384
*) (ftie
+ 2);
2453 fte_mic
= _ftie
->mic
;
2454 elem_count
= &_ftie
->mic_control
[1];
2456 struct rsn_ftie
*_ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2458 fte_mic
= _ftie
->mic
;
2459 elem_count
= &_ftie
->mic_control
[1];
2461 if (auth_alg
== WLAN_AUTH_FT
)
2462 *elem_count
= 3; /* Information element count */
2465 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
, use_sha384
) == 0
2467 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2469 if (auth_alg
== WLAN_AUTH_FT
)
2471 ieee802_11_ie_count(ric_start
,
2474 if (ric_start
== pos
)
2477 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2479 kck_len
= sm
->PTK
.kck2_len
;
2482 kck_len
= sm
->PTK
.kck_len
;
2484 if (auth_alg
== WLAN_AUTH_FT
&&
2485 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2486 mdie
, mdie_len
, ftie
, ftie_len
,
2488 ric_start
, ric_start
? pos
- ric_start
: 0,
2490 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2494 os_free(sm
->assoc_resp_ftie
);
2495 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2496 if (!sm
->assoc_resp_ftie
)
2498 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2504 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2506 enum wpa_alg alg
, const u8
*addr
, int idx
,
2507 u8
*key
, size_t key_len
)
2509 if (wpa_auth
->cb
->set_key
== NULL
)
2511 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2516 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
2521 /* MLME-SETKEYS.request(PTK) */
2522 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2523 klen
= wpa_cipher_key_len(sm
->pairwise
);
2524 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2525 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2526 "PTK configuration", sm
->pairwise
);
2530 if (sm
->tk_already_set
) {
2531 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2532 * PN in the driver */
2533 wpa_printf(MSG_DEBUG
,
2534 "FT: Do not re-install same PTK to the driver");
2538 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2539 * most likely without this.. At the moment, STA entry is added only
2540 * after association has been completed. This function will be called
2541 * again after association to get the PTK configured, but that could be
2542 * optimized by adding the STA entry earlier.
2544 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
2548 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2549 sm
->pairwise_set
= TRUE
;
2550 sm
->tk_already_set
= TRUE
;
2554 /* Derive PMK-R1 from PSK, check all available PSK */
2555 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2556 const u8
*req_pmk_r1_name
,
2557 u8
*out_pmk_r1
, int *out_pairwise
,
2558 struct vlan_description
*out_vlan
,
2559 const u8
**out_identity
, size_t *out_identity_len
,
2560 const u8
**out_radius_cui
,
2561 size_t *out_radius_cui_len
,
2562 int *out_session_timeout
)
2564 const u8
*pmk
= NULL
;
2565 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2566 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2567 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2568 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2569 const u8
*r0kh
= sm
->r0kh_id
;
2570 size_t r0kh_len
= sm
->r0kh_id_len
;
2571 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2572 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2573 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2576 pairwise
= sm
->pairwise
;
2579 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2584 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2586 pmk_r0
, pmk_r0_name
, 0) < 0 ||
2587 wpa_derive_pmk_r1(pmk_r0
, PMK_LEN
, pmk_r0_name
, r1kh
,
2588 sm
->addr
, pmk_r1
, pmk_r1_name
) < 0 ||
2589 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2590 WPA_PMK_NAME_LEN
) != 0)
2593 /* We found a PSK that matches the requested pmk_r1_name */
2594 wpa_printf(MSG_DEBUG
,
2595 "FT: Found PSK to generate PMK-R1 locally");
2596 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2598 *out_pairwise
= pairwise
;
2600 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2601 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2602 MACSTR
, MAC2STR(sm
->addr
));
2606 if (out_identity
&& out_identity_len
) {
2607 *out_identity_len
= wpa_ft_get_identity(
2608 sm
->wpa_auth
, sm
->addr
, out_identity
);
2611 if (out_radius_cui
&& out_radius_cui_len
) {
2612 *out_radius_cui_len
= wpa_ft_get_radius_cui(
2613 sm
->wpa_auth
, sm
->addr
, out_radius_cui
);
2616 if (out_session_timeout
) {
2617 *out_session_timeout
= wpa_ft_get_session_timeout(
2618 sm
->wpa_auth
, sm
->addr
);
2624 wpa_printf(MSG_DEBUG
,
2625 "FT: Did not find PSK to generate PMK-R1 locally");
2630 /* Detect the configuration the station asked for.
2631 * Required to detect FT-PSK and pairwise cipher.
2633 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2634 struct wpa_ft_ies
*parse
)
2636 int key_mgmt
, ciphers
;
2638 if (sm
->wpa_key_mgmt
)
2641 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2643 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2644 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2647 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2648 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2649 #ifdef CONFIG_SHA384
2650 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X_SHA384
)
2651 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X_SHA384
;
2652 #endif /* CONFIG_SHA384 */
2653 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2654 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2656 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2657 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2658 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2659 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2660 #endif /* CONFIG_FILS */
2661 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2663 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2665 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2668 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2674 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2675 struct wpa_state_machine
*sm
,
2676 const u8
*r0kh_id
, size_t r0kh_id_len
,
2677 const u8
*req_pmk_r0_name
,
2678 const u8
*req_pmk_r1_name
,
2679 u8
*out_pmk_r1
, int *out_pairwise
,
2680 struct vlan_description
*vlan
,
2681 const u8
**identity
, size_t *identity_len
,
2682 const u8
**radius_cui
,
2683 size_t *radius_cui_len
,
2684 int *out_session_timeout
)
2686 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2687 const struct wpa_ft_pmk_r0_sa
*r0
;
2688 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2690 int session_timeout
= 0;
2691 struct os_reltime now
;
2693 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2694 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2696 return -1; /* not our R0KH-ID */
2698 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2699 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2701 return -1; /* no matching PMKR0Name in local cache */
2703 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2705 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_len
, r0
->pmk_r0_name
,
2706 conf
->r1_key_holder
,
2707 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2709 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, r0
->pmk_r0_len
);
2710 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2712 os_get_reltime(&now
);
2714 expires_in
= r0
->expiration
- now
.sec
;
2716 if (r0
->session_timeout
)
2717 session_timeout
= r0
->session_timeout
- now
.sec
;
2719 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, r0
->pmk_r0_len
,
2721 sm
->pairwise
, r0
->vlan
, expires_in
, session_timeout
,
2722 r0
->identity
, r0
->identity_len
,
2723 r0
->radius_cui
, r0
->radius_cui_len
);
2725 *out_pairwise
= sm
->pairwise
;
2730 os_memset(vlan
, 0, sizeof(*vlan
));
2733 if (identity
&& identity_len
) {
2734 *identity
= r0
->identity
;
2735 *identity_len
= r0
->identity_len
;
2738 if (radius_cui
&& radius_cui_len
) {
2739 *radius_cui
= r0
->radius_cui
;
2740 *radius_cui_len
= r0
->radius_cui_len
;
2743 *out_session_timeout
= session_timeout
;
2749 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2750 const u8
*ies
, size_t ies_len
,
2751 u8
**resp_ies
, size_t *resp_ies_len
)
2753 struct rsn_mdie
*mdie
;
2754 u8 pmk_r1
[PMK_LEN_MAX
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2755 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2756 struct wpa_auth_config
*conf
;
2757 struct wpa_ft_ies parse
;
2761 int pairwise
, session_timeout
= 0;
2762 struct vlan_description vlan
;
2763 const u8
*identity
, *radius_cui
;
2764 size_t identity_len
= 0, radius_cui_len
= 0;
2771 sm
->pmk_r1_name_valid
= 0;
2772 conf
= &sm
->wpa_auth
->conf
;
2774 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2777 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, -1)) {
2778 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2779 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2781 use_sha384
= wpa_key_mgmt_sha384(parse
.key_mgmt
);
2782 pmk_r1_len
= use_sha384
? SHA384_MAC_LEN
: PMK_LEN
;
2784 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2785 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2786 os_memcmp(mdie
->mobility_domain
,
2787 sm
->wpa_auth
->conf
.mobility_domain
,
2788 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2789 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2790 return WLAN_STATUS_INVALID_MDIE
;
2794 struct rsn_ftie_sha384
*ftie
;
2796 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
2797 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2798 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2799 return WLAN_STATUS_INVALID_FTIE
;
2802 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2804 struct rsn_ftie
*ftie
;
2806 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2807 if (!ftie
|| parse
.ftie_len
< sizeof(*ftie
)) {
2808 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2809 return WLAN_STATUS_INVALID_FTIE
;
2812 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2815 if (parse
.r0kh_id
== NULL
) {
2816 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2817 return WLAN_STATUS_INVALID_FTIE
;
2820 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2821 parse
.r0kh_id
, parse
.r0kh_id_len
);
2822 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2823 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2825 if (parse
.rsn_pmkid
== NULL
) {
2826 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2827 return WLAN_STATUS_INVALID_PMKID
;
2830 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2831 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2833 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2834 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2835 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2836 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2838 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2839 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2840 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2842 if (conf
->ft_psk_generate_local
&&
2843 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2844 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
2845 &vlan
, &identity
, &identity_len
,
2846 &radius_cui
, &radius_cui_len
,
2847 &session_timeout
) < 0)
2848 return WLAN_STATUS_INVALID_PMKID
;
2849 wpa_printf(MSG_DEBUG
,
2850 "FT: Generated PMK-R1 for FT-PSK locally");
2851 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2852 pmk_r1
, &pmk_r1_len
, &pairwise
, &vlan
,
2853 &identity
, &identity_len
, &radius_cui
,
2854 &radius_cui_len
, &session_timeout
) < 0) {
2855 wpa_printf(MSG_DEBUG
,
2856 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2857 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2858 parse
.r0kh_id
, parse
.r0kh_id_len
,
2860 pmk_r1_name
, pmk_r1
, &pairwise
,
2861 &vlan
, &identity
, &identity_len
,
2862 &radius_cui
, &radius_cui_len
,
2863 &session_timeout
) == 0) {
2864 wpa_printf(MSG_DEBUG
,
2865 "FT: Generated PMK-R1 based on local PMK-R0");
2866 goto pmk_r1_derived
;
2869 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2870 wpa_printf(MSG_DEBUG
,
2871 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2872 return WLAN_STATUS_INVALID_PMKID
;
2875 return -1; /* Status pending */
2877 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2881 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, pmk_r1_len
);
2882 sm
->pmk_r1_name_valid
= 1;
2883 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2885 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2886 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2888 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2891 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2892 sm
->SNonce
, WPA_NONCE_LEN
);
2893 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2894 sm
->ANonce
, WPA_NONCE_LEN
);
2896 if (wpa_pmk_r1_to_ptk(pmk_r1
, pmk_r1_len
, sm
->SNonce
, sm
->ANonce
,
2897 sm
->addr
, sm
->wpa_auth
->addr
, pmk_r1_name
,
2898 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
2900 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2902 sm
->pairwise
= pairwise
;
2903 sm
->PTK_valid
= TRUE
;
2904 sm
->tk_already_set
= FALSE
;
2905 wpa_ft_install_ptk(sm
);
2907 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2908 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
2909 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2911 if (wpa_ft_set_identity(sm
->wpa_auth
, sm
->addr
,
2912 identity
, identity_len
) < 0 ||
2913 wpa_ft_set_radius_cui(sm
->wpa_auth
, sm
->addr
,
2914 radius_cui
, radius_cui_len
) < 0) {
2915 wpa_printf(MSG_DEBUG
, "FT: Failed to configure identity/CUI");
2916 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2918 wpa_ft_set_session_timeout(sm
->wpa_auth
, sm
->addr
, session_timeout
);
2920 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
2921 2 + FT_R1KH_ID_LEN
+ 200;
2922 *resp_ies
= os_zalloc(buflen
);
2923 if (*resp_ies
== NULL
)
2927 end
= *resp_ies
+ buflen
;
2929 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
2934 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
2939 ret
= wpa_write_ftie(conf
, use_sha384
, parse
.r0kh_id
, parse
.r0kh_id_len
,
2940 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
2945 *resp_ies_len
= pos
- *resp_ies
;
2947 return WLAN_STATUS_SUCCESS
;
2951 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2955 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
2956 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
2957 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
2958 u16 auth_transaction
, u16 status
,
2959 const u8
*ies
, size_t ies_len
),
2964 size_t resp_ies_len
;
2968 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
2969 "WPA SM not available");
2973 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
2974 " BSSID=" MACSTR
" transaction=%d",
2975 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
2976 sm
->ft_pending_cb
= cb
;
2977 sm
->ft_pending_cb_ctx
= ctx
;
2978 sm
->ft_pending_auth_transaction
= auth_transaction
;
2979 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2980 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
2983 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
2988 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
2989 " auth_transaction=%d status=%d",
2990 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
2991 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2992 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
2993 resp_ies
, resp_ies_len
);
2998 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
3001 struct wpa_ft_ies parse
;
3002 struct rsn_mdie
*mdie
;
3003 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
3004 size_t mic_len
= 16;
3009 const u8
*anonce
, *snonce
, *fte_mic
;
3013 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3015 use_sha384
= wpa_key_mgmt_sha384(sm
->wpa_key_mgmt
);
3017 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
3019 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
, use_sha384
) < 0) {
3020 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
3021 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3024 if (parse
.rsn
== NULL
) {
3025 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
3026 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3029 if (parse
.rsn_pmkid
== NULL
) {
3030 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
3031 return WLAN_STATUS_INVALID_PMKID
;
3034 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
3036 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
3037 "with the PMKR1Name derived from auth request");
3038 return WLAN_STATUS_INVALID_PMKID
;
3041 mdie
= (struct rsn_mdie
*) parse
.mdie
;
3042 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
3043 os_memcmp(mdie
->mobility_domain
,
3044 sm
->wpa_auth
->conf
.mobility_domain
,
3045 MOBILITY_DOMAIN_ID_LEN
) != 0) {
3046 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
3047 return WLAN_STATUS_INVALID_MDIE
;
3051 struct rsn_ftie_sha384
*ftie
;
3053 ftie
= (struct rsn_ftie_sha384
*) parse
.ftie
;
3054 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3055 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3056 return WLAN_STATUS_INVALID_FTIE
;
3059 anonce
= ftie
->anonce
;
3060 snonce
= ftie
->snonce
;
3061 fte_elem_count
= ftie
->mic_control
[1];
3062 fte_mic
= ftie
->mic
;
3064 struct rsn_ftie
*ftie
;
3066 ftie
= (struct rsn_ftie
*) parse
.ftie
;
3067 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
3068 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
3069 return WLAN_STATUS_INVALID_FTIE
;
3072 anonce
= ftie
->anonce
;
3073 snonce
= ftie
->snonce
;
3074 fte_elem_count
= ftie
->mic_control
[1];
3075 fte_mic
= ftie
->mic
;
3078 if (os_memcmp(snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
3079 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
3080 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
3081 snonce
, WPA_NONCE_LEN
);
3082 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
3083 sm
->SNonce
, WPA_NONCE_LEN
);
3084 return WLAN_STATUS_INVALID_FTIE
;
3087 if (os_memcmp(anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
3088 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
3089 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
3090 anonce
, WPA_NONCE_LEN
);
3091 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
3092 sm
->ANonce
, WPA_NONCE_LEN
);
3093 return WLAN_STATUS_INVALID_FTIE
;
3097 if (parse
.r0kh_id
== NULL
) {
3098 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
3099 return WLAN_STATUS_INVALID_FTIE
;
3102 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
3103 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
3105 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
3106 "the current R0KH-ID");
3107 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
3108 parse
.r0kh_id
, parse
.r0kh_id_len
);
3109 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
3110 sm
->r0kh_id
, sm
->r0kh_id_len
);
3111 return WLAN_STATUS_INVALID_FTIE
;
3114 if (parse
.r1kh_id
== NULL
) {
3115 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
3116 return WLAN_STATUS_INVALID_FTIE
;
3119 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
3120 FT_R1KH_ID_LEN
) != 0) {
3121 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
3123 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
3124 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
3125 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
3126 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
3127 return WLAN_STATUS_INVALID_FTIE
;
3130 if (parse
.rsn_pmkid
== NULL
||
3131 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
3133 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
3134 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
3135 return WLAN_STATUS_INVALID_PMKID
;
3140 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
3141 if (fte_elem_count
!= count
) {
3142 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
3143 "Control: received %u expected %u",
3144 fte_elem_count
, count
);
3145 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3148 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
3150 kck_len
= sm
->PTK
.kck2_len
;
3153 kck_len
= sm
->PTK
.kck_len
;
3155 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
3156 parse
.mdie
- 2, parse
.mdie_len
+ 2,
3157 parse
.ftie
- 2, parse
.ftie_len
+ 2,
3158 parse
.rsn
- 2, parse
.rsn_len
+ 2,
3159 parse
.ric
, parse
.ric_len
,
3161 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
3162 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3165 if (os_memcmp_const(mic
, fte_mic
, mic_len
) != 0) {
3166 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
3167 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
3168 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
3169 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
3171 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
3172 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
3173 parse
.mdie
- 2, parse
.mdie_len
+ 2);
3174 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
3175 parse
.ftie
- 2, parse
.ftie_len
+ 2);
3176 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
3177 parse
.rsn
- 2, parse
.rsn_len
+ 2);
3178 return WLAN_STATUS_INVALID_FTIE
;
3181 return WLAN_STATUS_SUCCESS
;
3185 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
3187 const u8
*sta_addr
, *target_ap
;
3191 struct ft_rrb_frame
*frame
;
3197 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3198 * FT Request action frame body[variable]
3202 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
3203 "(len=%lu)", (unsigned long) len
);
3208 sta_addr
= data
+ 2;
3209 target_ap
= data
+ 8;
3213 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
3214 " Target AP=" MACSTR
" Action=%d)",
3215 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
3217 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
3218 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
3219 "STA=" MACSTR
" STA-Address=" MACSTR
,
3220 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
3225 * Do some sanity checking on the target AP address (not own and not
3226 * broadcast. This could be extended to filter based on a list of known
3227 * APs in the MD (if such a list were configured).
3229 if ((target_ap
[0] & 0x01) ||
3230 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
3231 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
3236 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
3238 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
3239 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
3243 /* RRB - Forward action frame to the target AP */
3244 frame
= os_malloc(sizeof(*frame
) + len
);
3247 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3248 frame
->packet_type
= FT_PACKET_REQUEST
;
3249 frame
->action_length
= host_to_le16(len
);
3250 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
3251 os_memcpy(frame
+ 1, data
, len
);
3253 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
3254 sizeof(*frame
) + len
);
3261 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
3262 u16 auth_transaction
, u16 resp
,
3263 const u8
*ies
, size_t ies_len
)
3265 struct wpa_state_machine
*sm
= ctx
;
3266 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
3268 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
3269 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
3273 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
3274 const u8
*current_ap
, const u8
*sta_addr
,
3275 const u8
*body
, size_t len
)
3277 struct wpa_state_machine
*sm
;
3280 size_t resp_ies_len
;
3283 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
3285 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
3290 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
3292 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
3293 sm
->ft_pending_cb_ctx
= sm
;
3294 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
3295 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3296 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
3299 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
3304 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
3305 resp_ies
, resp_ies_len
);
3311 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
3312 const u8
*current_ap
, const u8
*sta_addr
,
3313 u16 status
, const u8
*resp_ies
,
3314 size_t resp_ies_len
)
3316 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
3318 struct ft_rrb_frame
*frame
;
3321 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
3322 " CurrentAP=" MACSTR
" status=%d",
3323 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
3324 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3326 /* RRB - Forward action frame response to the Current AP */
3329 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3330 * Status_Code[2] FT Request action frame body[variable]
3332 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
3334 frame
= os_malloc(sizeof(*frame
) + rlen
);
3337 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3338 frame
->packet_type
= FT_PACKET_RESPONSE
;
3339 frame
->action_length
= host_to_le16(rlen
);
3340 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
3341 pos
= (u8
*) (frame
+ 1);
3342 *pos
++ = WLAN_ACTION_FT
;
3343 *pos
++ = 2; /* Action: Response */
3344 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
3346 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
3348 WPA_PUT_LE16(pos
, status
);
3351 os_memcpy(pos
, resp_ies
, resp_ies_len
);
3353 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
3354 sizeof(*frame
) + rlen
);
3361 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
3362 const struct tlv_list
*tlvs
,
3363 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3364 const u8
*r1kh_id
, const u8
*s1kh_id
,
3365 const struct tlv_list
*tlv_auth
,
3366 const u8
*src_addr
, u8 type
,
3367 u8
**packet
, size_t *packet_len
)
3369 u8 pmk_r1
[PMK_LEN_MAX
];
3370 size_t pmk_r1_len
= pmk_r0
->pmk_r0_len
;
3371 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3372 u8 f_pairwise
[sizeof(le16
)];
3373 u8 f_expires_in
[sizeof(le16
)];
3374 u8 f_session_timeout
[sizeof(le32
)];
3376 int session_timeout
;
3377 struct os_reltime now
;
3379 struct tlv_list sess_tlv
[] = {
3380 { .type
= FT_RRB_PMK_R1
, .len
= pmk_r1_len
,
3382 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3383 .data
= pmk_r1_name
},
3384 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3385 .data
= f_pairwise
},
3386 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3387 .data
= f_expires_in
},
3388 { .type
= FT_RRB_IDENTITY
, .len
= pmk_r0
->identity_len
,
3389 .data
= pmk_r0
->identity
},
3390 { .type
= FT_RRB_RADIUS_CUI
, .len
= pmk_r0
->radius_cui_len
,
3391 .data
= pmk_r0
->radius_cui
},
3392 { .type
= FT_RRB_SESSION_TIMEOUT
,
3393 .len
= sizeof(f_session_timeout
),
3394 .data
= f_session_timeout
},
3395 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3398 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_len
,
3399 pmk_r0
->pmk_r0_name
, r1kh_id
,
3400 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3402 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1 (for peer AP)",
3403 pmk_r1
, pmk_r1_len
);
3404 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name (for peer AP)",
3405 pmk_r1_name
, WPA_PMK_NAME_LEN
);
3406 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3408 os_get_reltime(&now
);
3409 if (pmk_r0
->expiration
> now
.sec
)
3410 expires_in
= pmk_r0
->expiration
- now
.sec
;
3411 else if (pmk_r0
->expiration
)
3415 WPA_PUT_LE16(f_expires_in
, expires_in
);
3417 if (pmk_r0
->session_timeout
> now
.sec
)
3418 session_timeout
= pmk_r0
->session_timeout
- now
.sec
;
3419 else if (pmk_r0
->session_timeout
)
3420 session_timeout
= 1;
3422 session_timeout
= 0;
3423 WPA_PUT_LE32(f_session_timeout
, session_timeout
);
3425 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3426 pmk_r0
->vlan
, src_addr
, type
,
3427 packet
, packet_len
);
3429 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
3435 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3437 const u8
*enc
, size_t enc_len
,
3438 const u8
*auth
, size_t auth_len
,
3441 const char *msgtype
= "pull request";
3442 u8
*plain
= NULL
, *packet
= NULL
;
3443 size_t plain_len
= 0, packet_len
= 0;
3444 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3448 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3449 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3450 size_t f_pmk_r0_name_len
;
3451 const struct wpa_ft_pmk_r0_sa
*r0
;
3453 struct tlv_list resp
[2];
3454 struct tlv_list resp_auth
[5];
3455 struct ft_rrb_seq f_seq
;
3457 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3459 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3460 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3462 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3463 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3467 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3468 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3470 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3473 key_len
= sizeof(r1kh
->key
);
3474 } else if (r1kh_wildcard
) {
3475 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3476 key
= r1kh_wildcard
->key
;
3477 key_len
= sizeof(r1kh_wildcard
->key
);
3482 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3483 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3485 seq_ret
= FT_RRB_SEQ_DROP
;
3487 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3488 auth
, auth_len
, msgtype
, no_defer
);
3489 if (!no_defer
&& r1kh_wildcard
&&
3490 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3491 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3492 seq_ret
= FT_RRB_SEQ_DEFER
;
3495 if (seq_ret
== FT_RRB_SEQ_DROP
)
3498 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3499 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3500 &plain
, &plain_len
) < 0)
3504 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3506 wpa_auth
->conf
.rkh_pos_timeout
);
3510 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3511 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3512 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3513 enc
, enc_len
, auth
, auth_len
,
3514 &wpa_ft_rrb_rx_pull
);
3518 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3520 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3521 wpa_auth
->conf
.rkh_pos_timeout
);
3523 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3524 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3527 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3528 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3530 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3531 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3535 resp
[0].type
= FT_RRB_S1KH_ID
;
3536 resp
[0].len
= f_s1kh_id_len
;
3537 resp
[0].data
= f_s1kh_id
;
3538 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3540 resp
[1].data
= NULL
;
3542 resp_auth
[0].type
= FT_RRB_NONCE
;
3543 resp_auth
[0].len
= f_nonce_len
;
3544 resp_auth
[0].data
= f_nonce
;
3545 resp_auth
[1].type
= FT_RRB_SEQ
;
3546 resp_auth
[1].len
= sizeof(f_seq
);
3547 resp_auth
[1].data
= (u8
*) &f_seq
;
3548 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3549 resp_auth
[2].len
= f_r0kh_id_len
;
3550 resp_auth
[2].data
= f_r0kh_id
;
3551 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3552 resp_auth
[3].len
= f_r1kh_id_len
;
3553 resp_auth
[3].data
= f_r1kh_id
;
3554 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3555 resp_auth
[4].len
= 0;
3556 resp_auth
[4].data
= NULL
;
3558 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0) {
3559 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3560 ret
= wpa_ft_rrb_build(key
, key_len
, resp
, NULL
, resp_auth
,
3561 NULL
, wpa_auth
->addr
,
3562 FT_PACKET_R0KH_R1KH_RESP
,
3563 &packet
, &packet_len
);
3565 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
,
3566 f_s1kh_id
, resp_auth
, wpa_auth
->addr
,
3567 FT_PACKET_R0KH_R1KH_RESP
,
3568 &packet
, &packet_len
);
3572 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3573 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3584 /* @returns 0 on success
3586 * -2 if FR_RRB_PAIRWISE is missing
3588 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3589 const u8
*src_addr
, u8 type
,
3590 const u8
*enc
, size_t enc_len
,
3591 const u8
*auth
, size_t auth_len
,
3592 const char *msgtype
, u8
*s1kh_id_out
,
3593 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3595 const u8
*enc
, size_t enc_len
,
3596 const u8
*auth
, size_t auth_len
,
3600 size_t plain_len
= 0;
3601 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3605 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3606 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3607 const u8
*f_expires_in
;
3608 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3609 const u8
*f_identity
, *f_radius_cui
;
3610 const u8
*f_session_timeout
;
3611 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3612 size_t f_expires_in_len
;
3613 size_t f_identity_len
, f_radius_cui_len
;
3614 size_t f_session_timeout_len
;
3618 int session_timeout
;
3619 struct vlan_description vlan
;
3622 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3623 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3625 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3626 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3628 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3629 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3633 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3637 key_len
= sizeof(r0kh
->key
);
3638 } else if (r0kh_wildcard
) {
3639 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3640 key
= r0kh_wildcard
->key
;
3641 key_len
= sizeof(r0kh_wildcard
->key
);
3646 seq_ret
= FT_RRB_SEQ_DROP
;
3648 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3649 auth
, auth_len
, msgtype
,
3652 if (cb
&& r0kh_wildcard
&&
3653 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3654 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3655 seq_ret
= FT_RRB_SEQ_DEFER
;
3658 if (seq_ret
== FT_RRB_SEQ_DROP
)
3661 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3662 src_addr
, type
, &plain
, &plain_len
) < 0)
3666 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3667 f_r0kh_id
, f_r0kh_id_len
,
3668 wpa_auth
->conf
.rkh_pos_timeout
);
3672 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3673 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3674 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3675 enc
, enc_len
, auth
, auth_len
, cb
);
3679 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3681 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3682 wpa_auth
->conf
.rkh_pos_timeout
);
3684 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3685 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3688 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3691 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3692 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3695 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3696 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3697 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
3699 pmk_r1_len
= PMK_LEN
;
3700 if (wpa_ft_rrb_get_tlv(plain
, plain_len
, FT_RRB_PMK_R1
, &f_pmk_r1_len
,
3702 (f_pmk_r1_len
== PMK_LEN
|| f_pmk_r1_len
== SHA384_MAC_LEN
))
3703 pmk_r1_len
= f_pmk_r1_len
;
3704 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, pmk_r1_len
);
3705 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, pmk_r1_len
);
3707 pairwise
= WPA_GET_LE16(f_pairwise
);
3709 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
3712 expires_in
= WPA_GET_LE16(f_expires_in
);
3716 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
3719 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
3720 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
3721 wpa_ft_rrb_dump(plain
, plain_len
);
3725 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
3726 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
3728 RRB_GET_OPTIONAL(FT_RRB_IDENTITY
, identity
, msgtype
, -1);
3730 wpa_hexdump_ascii(MSG_DEBUG
, "FT: Identity", f_identity
,
3733 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI
, radius_cui
, msgtype
, -1);
3735 wpa_hexdump_ascii(MSG_DEBUG
, "FT: CUI", f_radius_cui
,
3738 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT
, session_timeout
, msgtype
,
3740 if (f_session_timeout
)
3741 session_timeout
= WPA_GET_LE32(f_session_timeout
);
3743 session_timeout
= 0;
3744 wpa_printf(MSG_DEBUG
, "FT: session_timeout %d", session_timeout
);
3746 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, pmk_r1_len
,
3748 pairwise
, &vlan
, expires_in
, session_timeout
,
3749 f_identity
, f_identity_len
, f_radius_cui
,
3750 f_radius_cui_len
) < 0)
3756 os_memset(plain
, 0, plain_len
);
3765 static void ft_finish_pull(struct wpa_state_machine
*sm
)
3769 size_t resp_ies_len
;
3772 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
3775 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
3776 wpabuf_len(sm
->ft_pending_req_ies
),
3777 &resp_ies
, &resp_ies_len
);
3779 /* this loop is broken by ft_pending_pull_left_retries */
3780 wpa_printf(MSG_DEBUG
,
3781 "FT: Callback postponed until response is available");
3784 wpabuf_free(sm
->ft_pending_req_ies
);
3785 sm
->ft_pending_req_ies
= NULL
;
3787 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
3788 " - status %u", MAC2STR(sm
->addr
), status
);
3790 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
3791 sm
->ft_pending_auth_transaction
+ 1, status
,
3792 resp_ies
, resp_ies_len
);
3797 struct ft_get_sta_ctx
{
3800 struct wpa_state_machine
*sm
;
3804 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3806 struct ft_get_sta_ctx
*info
= ctx
;
3808 if ((info
->s1kh_id
&&
3809 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3810 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3811 FT_RRB_NONCE_LEN
) != 0 ||
3812 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3821 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3823 const u8
*enc
, size_t enc_len
,
3824 const u8
*auth
, size_t auth_len
,
3827 const char *msgtype
= "pull response";
3829 struct ft_get_sta_ctx ctx
;
3830 u8 s1kh_id
[ETH_ALEN
];
3834 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3836 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3837 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3839 os_memset(&ctx
, 0, sizeof(ctx
));
3840 ctx
.nonce
= f_nonce
;
3841 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3842 /* nonce not found */
3843 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3847 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3848 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3849 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3859 ctx
.s1kh_id
= s1kh_id
;
3860 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3861 wpa_printf(MSG_DEBUG
,
3862 "FT: Response to a pending pull request for " MACSTR
,
3863 MAC2STR(ctx
.sm
->addr
));
3864 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3866 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3867 ft_finish_pull(ctx
.sm
);
3875 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
3877 const u8
*enc
, size_t enc_len
,
3878 const u8
*auth
, size_t auth_len
, int no_defer
)
3880 const char *msgtype
= "push";
3882 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
3884 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3885 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
3886 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
3893 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
3894 const u8
*src_addr
, int type
,
3895 const u8
*enc
, size_t enc_len
,
3896 const u8
*auth
, size_t auth_len
,
3897 struct ft_remote_seq
**rkh_seq
,
3898 u8
**key
, size_t *key_len
,
3899 struct ft_remote_r0kh
**r0kh_out
,
3900 struct ft_remote_r1kh
**r1kh_out
,
3901 struct ft_remote_r0kh
**r0kh_wildcard_out
,
3902 struct ft_remote_r1kh
**r1kh_wildcard_out
)
3904 struct ft_remote_r0kh
*r0kh
= NULL
;
3905 struct ft_remote_r1kh
*r1kh
= NULL
;
3906 const u8
*f_r0kh_id
, *f_r1kh_id
;
3907 size_t f_r0kh_id_len
, f_r1kh_id_len
;
3908 int to_r0kh
, to_r1kh
;
3910 size_t plain_len
= 0;
3911 struct ft_remote_r0kh
*r0kh_wildcard
;
3912 struct ft_remote_r1kh
*r1kh_wildcard
;
3914 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3915 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3917 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
3918 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
3920 if (to_r0kh
&& to_r1kh
) {
3921 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
3925 if (!to_r0kh
&& !to_r1kh
) {
3926 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
3931 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
3932 &r0kh
, &r0kh_wildcard
);
3933 if (!r0kh_wildcard
&&
3934 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3935 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
3936 f_r0kh_id
, f_r0kh_id_len
);
3941 *key_len
= sizeof(r0kh
->key
);
3943 *key
= r0kh_wildcard
->key
;
3944 *key_len
= sizeof(r0kh_wildcard
->key
);
3949 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
3951 if (!r1kh_wildcard
&&
3952 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3953 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
3954 f_r1kh_id
, FT_R1KH_ID_LEN
);
3959 *key_len
= sizeof(r1kh
->key
);
3961 *key
= r1kh_wildcard
->key
;
3962 *key_len
= sizeof(r1kh_wildcard
->key
);
3966 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
3967 src_addr
, type
, &plain
, &plain_len
) < 0)
3974 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
3975 src_addr
, f_r0kh_id
,
3981 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
3982 *rkh_seq
= r0kh
->seq
;
3985 if (r0kh_wildcard_out
)
3986 *r0kh_wildcard_out
= r0kh_wildcard
;
3991 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
3992 src_addr
, f_r1kh_id
,
3997 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
3998 *rkh_seq
= r1kh
->seq
;
4001 if (r1kh_wildcard_out
)
4002 *r1kh_wildcard_out
= r1kh_wildcard
;
4011 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
4013 const u8
*enc
, size_t enc_len
,
4014 const u8
*auth
, size_t auth_len
,
4018 struct ft_rrb_seq f_seq
;
4019 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
4020 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
4021 struct ft_remote_seq
*rkh_seq
= NULL
;
4022 u8
*packet
= NULL
, *key
= NULL
;
4023 size_t packet_len
= 0, key_len
= 0;
4024 struct tlv_list seq_resp_auth
[5];
4026 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
4028 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
4029 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4030 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
4033 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
4034 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
4036 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
4037 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
4039 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
4040 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4044 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
4045 seq_resp_auth
[0].len
= f_nonce_len
;
4046 seq_resp_auth
[0].data
= f_nonce
;
4047 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
4048 seq_resp_auth
[1].len
= sizeof(f_seq
);
4049 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
4050 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
4051 seq_resp_auth
[2].len
= f_r0kh_id_len
;
4052 seq_resp_auth
[2].data
= f_r0kh_id
;
4053 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
4054 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
4055 seq_resp_auth
[3].data
= f_r1kh_id
;
4056 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
4057 seq_resp_auth
[4].len
= 0;
4058 seq_resp_auth
[4].data
= NULL
;
4060 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
4061 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4062 &packet
, &packet_len
) < 0)
4065 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
4066 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
4076 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
4078 const u8
*enc
, size_t enc_len
,
4079 const u8
*auth
, size_t auth_len
,
4084 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
4085 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
4086 const u8
*f_nonce
, *f_seq
;
4087 size_t f_nonce_len
, f_seq_len
;
4088 struct ft_remote_seq
*rkh_seq
= NULL
;
4089 struct ft_remote_item
*item
;
4090 struct os_reltime now
, now_remote
;
4092 const struct ft_rrb_seq
*msg_both
;
4093 u32 msg_dom
, msg_seq
;
4095 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
4097 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
4098 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
4099 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
4100 &r1kh_wildcard
) < 0)
4103 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
4104 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
4108 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
4110 if (os_memcmp_const(f_nonce
, item
->nonce
,
4111 FT_RRB_NONCE_LEN
) != 0 ||
4112 os_get_reltime(&now
) < 0 ||
4113 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
4120 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
4125 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
4126 wpa_auth
->conf
.rkh_pos_timeout
);
4128 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
4132 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
4133 wpa_auth
->conf
.rkh_pos_timeout
);
4135 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
4138 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
4139 auth_len
, "seq response", 1);
4140 if (seq_ret
== FT_RRB_SEQ_OK
) {
4141 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
4142 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
4143 auth_len
, "seq response");
4145 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
4147 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
4149 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
4151 msg_dom
= le_to_host32(msg_both
->dom
);
4152 msg_seq
= le_to_host32(msg_both
->seq
);
4153 now_remote
.sec
= le_to_host32(msg_both
->ts
);
4154 now_remote
.usec
= 0;
4156 rkh_seq
->rx
.num_last
= 2;
4157 rkh_seq
->rx
.dom
= msg_dom
;
4158 rkh_seq
->rx
.offsetidx
= 0;
4159 /* Accept some older, possibly cached packets as well */
4160 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
4161 dl_list_len(&rkh_seq
->rx
.queue
);
4162 rkh_seq
->rx
.last
[1] = msg_seq
;
4164 /* local time - offset = remote time
4165 * <=> local time - remote time = offset */
4166 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
4169 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
4177 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4178 const u8
*data
, size_t data_len
)
4180 struct ft_rrb_frame
*frame
;
4182 const u8
*pos
, *end
, *start
;
4184 const u8
*sta_addr
, *target_ap_addr
;
4186 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
4189 if (data_len
< sizeof(*frame
)) {
4190 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
4191 (unsigned long) data_len
);
4196 frame
= (struct ft_rrb_frame
*) pos
;
4197 pos
+= sizeof(*frame
);
4199 alen
= le_to_host16(frame
->action_length
);
4200 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
4201 "action_length=%d ap_address=" MACSTR
,
4202 frame
->frame_type
, frame
->packet_type
, alen
,
4203 MAC2STR(frame
->ap_address
));
4205 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
4206 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
4207 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
4208 "unrecognized type %d", frame
->frame_type
);
4212 if (alen
> data_len
- sizeof(*frame
)) {
4213 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
4218 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
4220 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
4221 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
4222 "room for Action Frame body); alen=%lu",
4223 (unsigned long) alen
);
4229 if (*pos
!= WLAN_ACTION_FT
) {
4230 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
4239 target_ap_addr
= pos
;
4241 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
4242 MACSTR
" target_ap_addr=" MACSTR
,
4243 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
4245 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
4246 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
4249 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
4250 "RRB Request", action
);
4254 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
4255 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
4256 "RRB Request does not match with own "
4261 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
4262 sta_addr
, pos
, end
- pos
) < 0)
4264 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
4267 if (end
- pos
< 2) {
4268 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
4269 "code in RRB Response");
4272 status_code
= WPA_GET_LE16(pos
);
4275 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
4276 "(status_code=%d)", status_code
);
4278 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
4281 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
4282 "packet_type %d", frame
->packet_type
);
4287 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
4295 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4296 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
4299 const u8
*auth
, *enc
;
4303 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
4304 MACSTR
, MAC2STR(src_addr
));
4305 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
4307 if (is_multicast_ether_addr(src_addr
)) {
4308 wpa_printf(MSG_DEBUG
,
4309 "FT: RRB-OUI received frame from multicast address "
4310 MACSTR
, MAC2STR(src_addr
));
4314 if (is_multicast_ether_addr(dst_addr
)) {
4315 wpa_printf(MSG_DEBUG
,
4316 "FT: RRB-OUI received frame from remote AP " MACSTR
4317 " to multicast address " MACSTR
,
4318 MAC2STR(src_addr
), MAC2STR(dst_addr
));
4322 if (data_len
< sizeof(u16
)) {
4323 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4327 alen
= WPA_GET_LE16(data
);
4328 if (data_len
< sizeof(u16
) + alen
) {
4329 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4333 auth
= data
+ sizeof(u16
);
4334 enc
= data
+ sizeof(u16
) + alen
;
4335 elen
= data_len
- sizeof(u16
) - alen
;
4337 switch (oui_suffix
) {
4338 case FT_PACKET_R0KH_R1KH_PULL
:
4339 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4342 case FT_PACKET_R0KH_R1KH_RESP
:
4343 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4346 case FT_PACKET_R0KH_R1KH_PUSH
:
4347 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4350 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
4351 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4354 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
4355 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
4362 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
4363 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
4364 struct ft_remote_r1kh
*r1kh
,
4369 struct ft_rrb_seq f_seq
;
4370 struct tlv_list push
[] = {
4371 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
4373 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
4374 .data
= pmk_r0
->pmk_r0_name
},
4375 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4377 struct tlv_list push_auth
[] = {
4378 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
4379 .data
= (u8
*) &f_seq
},
4380 { .type
= FT_RRB_R0KH_ID
,
4381 .len
= wpa_auth
->conf
.r0_key_holder_len
,
4382 .data
= wpa_auth
->conf
.r0_key_holder
},
4383 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
4385 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4388 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
4389 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4393 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
4394 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
4395 FT_PACKET_R0KH_R1KH_PUSH
,
4396 &packet
, &packet_len
) < 0)
4399 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4400 packet
, packet_len
);
4407 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
4409 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
4410 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
4411 struct ft_remote_r1kh
*r1kh
;
4413 if (!wpa_auth
->conf
.pmk_r1_push
)
4415 if (!wpa_auth
->conf
.r1kh_list
)
4418 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
4419 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4426 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4428 r0
->pmk_r1_pushed
= 1;
4430 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4431 "for STA " MACSTR
, MAC2STR(addr
));
4433 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4434 if (is_zero_ether_addr(r1kh
->addr
) ||
4435 is_zero_ether_addr(r1kh
->id
))
4437 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4439 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4443 #endif /* CONFIG_IEEE80211R_AP */