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/random.h"
20 #include "ap_config.h"
21 #include "ieee802_11.h"
24 #include "wpa_auth_i.h"
27 #ifdef CONFIG_IEEE80211R_AP
29 const unsigned int ftRRBseqTimeout
= 10;
30 const unsigned int ftRRBmaxQueueLen
= 100;
33 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
34 const u8
*current_ap
, const u8
*sta_addr
,
35 u16 status
, const u8
*resp_ies
,
37 static void ft_finish_pull(struct wpa_state_machine
*sm
);
38 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
);
39 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
);
49 * wpa_ft_rrb_decrypt - Decrypt FT RRB message
50 * @key: AES-SIV key for AEAD
51 * @key_len: Length of key in octets
52 * @enc: Pointer to encrypted TLVs
53 * @enc_len: Length of encrypted TLVs in octets
54 * @auth: Pointer to authenticated TLVs
55 * @auth_len: Length of authenticated TLVs in octets
56 * @src_addr: MAC address of the frame sender
57 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
58 * @plain: Pointer to return the pointer to the allocated plaintext buffer;
59 * needs to be freed by the caller if not NULL;
60 * will only be returned on success
61 * @plain_len: Pointer to return the length of the allocated plaintext buffer
63 * Returns: 0 on success, -1 on error
65 static int wpa_ft_rrb_decrypt(const u8
*key
, const size_t key_len
,
66 const u8
*enc
, const size_t enc_len
,
67 const u8
*auth
, const size_t auth_len
,
68 const u8
*src_addr
, u8 type
,
69 u8
**plain
, size_t *plain_size
)
71 const u8
*ad
[3] = { src_addr
, auth
, &type
};
72 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
74 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypt using key", key
, key_len
);
76 if (!key
) { /* skip decryption */
77 *plain
= os_memdup(enc
, enc_len
);
78 if (enc_len
> 0 && !*plain
)
81 *plain_size
= enc_len
;
89 if (enc_len
< AES_BLOCK_SIZE
)
92 *plain
= os_zalloc(enc_len
- AES_BLOCK_SIZE
);
96 if (aes_siv_decrypt(key
, key_len
, enc
, enc_len
, 3, ad
, ad_len
,
100 *plain_size
= enc_len
- AES_BLOCK_SIZE
;
101 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): decrypted TLVs",
102 *plain
, *plain_size
);
109 wpa_printf(MSG_ERROR
, "FT(RRB): Failed to decrypt");
115 /* get first tlv record in packet matching type
116 * @data (decrypted) packet
117 * @return 0 on success else -1
119 static int wpa_ft_rrb_get_tlv(const u8
*plain
, size_t plain_len
,
120 u16 type
, size_t *tlv_len
, const u8
**tlv_data
)
122 const struct ft_rrb_tlv
*f
;
128 type16
= host_to_le16(type
);
130 while (left
>= sizeof(*f
)) {
131 f
= (const struct ft_rrb_tlv
*) plain
;
135 len
= le_to_host16(f
->len
);
138 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
142 if (f
->type
== type16
) {
156 static void wpa_ft_rrb_dump(const u8
*plain
, const size_t plain_len
)
158 const struct ft_rrb_tlv
*f
;
164 wpa_printf(MSG_DEBUG
, "FT: RRB dump message");
165 while (left
>= sizeof(*f
)) {
166 f
= (const struct ft_rrb_tlv
*) plain
;
170 len
= le_to_host16(f
->len
);
172 wpa_printf(MSG_DEBUG
, "FT: RRB TLV type = %d, len = %zu",
173 le_to_host16(f
->type
), len
);
176 wpa_printf(MSG_DEBUG
,
177 "FT: RRB message truncated: left %zu bytes, need %zu",
182 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV data", plain
, len
);
189 wpa_hexdump(MSG_DEBUG
, "FT: RRB TLV padding", plain
, left
);
191 wpa_printf(MSG_DEBUG
, "FT: RRB dump message end");
195 static int cmp_int(const void *a
, const void *b
)
205 static int wpa_ft_rrb_get_tlv_vlan(const u8
*plain
, const size_t plain_len
,
206 struct vlan_description
*vlan
)
208 struct ft_rrb_tlv
*f
;
217 os_memset(vlan
, 0, sizeof(*vlan
));
219 while (left
>= sizeof(*f
)) {
220 f
= (struct ft_rrb_tlv
*) plain
;
225 len
= le_to_host16(f
->len
);
226 type
= le_to_host16(f
->type
);
229 wpa_printf(MSG_DEBUG
, "FT: RRB message truncated");
233 if (type
!= FT_RRB_VLAN_UNTAGGED
&& type
!= FT_RRB_VLAN_TAGGED
)
236 if (type
== FT_RRB_VLAN_UNTAGGED
&& len
!= sizeof(le16
)) {
237 wpa_printf(MSG_DEBUG
,
238 "FT: RRB VLAN_UNTAGGED invalid length");
242 if (type
== FT_RRB_VLAN_TAGGED
&& len
% sizeof(le16
) != 0) {
243 wpa_printf(MSG_DEBUG
,
244 "FT: RRB VLAN_TAGGED invalid length");
248 while (len
>= sizeof(le16
)) {
249 vlan_id
= WPA_GET_LE16(plain
);
250 plain
+= sizeof(le16
);
251 left
-= sizeof(le16
);
254 if (vlan_id
<= 0 || vlan_id
> MAX_VLAN_ID
) {
255 wpa_printf(MSG_DEBUG
,
256 "FT: RRB VLAN ID invalid %d",
261 if (type
== FT_RRB_VLAN_UNTAGGED
)
262 vlan
->untagged
= vlan_id
;
264 if (type
== FT_RRB_VLAN_TAGGED
&&
265 taggedidx
< MAX_NUM_TAGGED_VLAN
) {
266 vlan
->tagged
[taggedidx
] = vlan_id
;
268 } else if (type
== FT_RRB_VLAN_TAGGED
) {
269 wpa_printf(MSG_DEBUG
, "FT: RRB too many VLANs");
279 qsort(vlan
->tagged
, taggedidx
, sizeof(int), cmp_int
);
281 vlan
->notempty
= vlan
->untagged
|| vlan
->tagged
[0];
287 static size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
295 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
296 tlv_len
+= sizeof(struct ft_rrb_tlv
);
297 tlv_len
+= tlvs
[i
].len
;
304 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
309 struct ft_rrb_tlv
*hdr
;
317 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
318 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
320 tlv_len
+= sizeof(*hdr
);
321 hdr
= (struct ft_rrb_tlv
*) pos
;
322 hdr
->type
= host_to_le16(tlvs
[i
].type
);
323 hdr
->len
= host_to_le16(tlvs
[i
].len
);
324 pos
= start
+ tlv_len
;
326 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
328 if (tlvs
[i
].len
== 0)
330 tlv_len
+= tlvs
[i
].len
;
331 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
332 pos
= start
+ tlv_len
;
339 static size_t wpa_ft_vlan_len(const struct vlan_description
*vlan
)
344 if (!vlan
|| !vlan
->notempty
)
347 if (vlan
->untagged
) {
348 tlv_len
+= sizeof(struct ft_rrb_tlv
);
349 tlv_len
+= sizeof(le16
);
352 tlv_len
+= sizeof(struct ft_rrb_tlv
);
353 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++)
354 tlv_len
+= sizeof(le16
);
360 static size_t wpa_ft_vlan_lin(const struct vlan_description
*vlan
,
361 u8
*start
, u8
*endpos
)
365 struct ft_rrb_tlv
*hdr
;
368 if (!vlan
|| !vlan
->notempty
)
372 if (vlan
->untagged
) {
373 tlv_len
+= sizeof(*hdr
);
374 if (start
+ tlv_len
> endpos
)
376 hdr
= (struct ft_rrb_tlv
*) pos
;
377 hdr
->type
= host_to_le16(FT_RRB_VLAN_UNTAGGED
);
378 hdr
->len
= host_to_le16(sizeof(le16
));
379 pos
= start
+ tlv_len
;
381 tlv_len
+= sizeof(le16
);
382 if (start
+ tlv_len
> endpos
)
384 WPA_PUT_LE16(pos
, vlan
->untagged
);
385 pos
= start
+ tlv_len
;
388 if (!vlan
->tagged
[0])
391 tlv_len
+= sizeof(*hdr
);
392 if (start
+ tlv_len
> endpos
)
394 hdr
= (struct ft_rrb_tlv
*) pos
;
395 hdr
->type
= host_to_le16(FT_RRB_VLAN_TAGGED
);
396 len
= 0; /* len is computed below */
397 pos
= start
+ tlv_len
;
399 for (i
= 0; i
< MAX_NUM_TAGGED_VLAN
&& vlan
->tagged
[i
]; i
++) {
400 tlv_len
+= sizeof(le16
);
401 if (start
+ tlv_len
> endpos
)
404 WPA_PUT_LE16(pos
, vlan
->tagged
[i
]);
405 pos
= start
+ tlv_len
;
408 hdr
->len
= host_to_le16(len
);
414 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
415 const struct tlv_list
*tlvs2
,
416 const struct vlan_description
*vlan
,
417 u8
**plain
, size_t *plain_len
)
422 tlv_len
= wpa_ft_tlv_len(tlvs1
);
423 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
424 tlv_len
+= wpa_ft_vlan_len(vlan
);
426 *plain_len
= tlv_len
;
427 *plain
= os_zalloc(tlv_len
);
429 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
434 endpos
= *plain
+ tlv_len
;
435 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
436 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
437 pos
+= wpa_ft_vlan_lin(vlan
, pos
, endpos
);
441 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
455 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
456 const u8
*plain
, const size_t plain_len
,
457 const u8
*auth
, const size_t auth_len
,
458 const u8
*src_addr
, u8 type
, u8
*enc
)
460 const u8
*ad
[3] = { src_addr
, auth
, &type
};
461 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
463 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
465 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
468 /* encryption not needed, return plaintext as packet */
469 os_memcpy(enc
, plain
, plain_len
);
470 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
471 3, ad
, ad_len
, enc
) < 0) {
472 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
481 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
482 * @key: AES-SIV key for AEAD
483 * @key_len: Length of key in octets
484 * @tlvs_enc0: First set of to-be-encrypted TLVs
485 * @tlvs_enc1: Second set of to-be-encrypted TLVs
486 * @tlvs_auth: Set of to-be-authenticated TLVs
487 * @src_addr: MAC address of the frame sender
488 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
489 * @packet Pointer to return the pointer to the allocated packet buffer;
490 * needs to be freed by the caller if not null;
491 * will only be returned on success
492 * @packet_len: Pointer to return the length of the allocated buffer in octets
493 * Returns: 0 on success, -1 on error
495 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
496 const struct tlv_list
*tlvs_enc0
,
497 const struct tlv_list
*tlvs_enc1
,
498 const struct tlv_list
*tlvs_auth
,
499 const struct vlan_description
*vlan
,
500 const u8
*src_addr
, u8 type
,
501 u8
**packet
, size_t *packet_len
)
503 u8
*plain
= NULL
, *auth
= NULL
, *pos
;
504 size_t plain_len
= 0, auth_len
= 0;
507 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, vlan
, &plain
, &plain_len
) < 0)
510 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, NULL
, &auth
, &auth_len
) < 0)
513 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
515 *packet_len
+= AES_BLOCK_SIZE
;
516 *packet
= os_zalloc(*packet_len
);
521 WPA_PUT_LE16(pos
, auth_len
);
523 os_memcpy(pos
, auth
, auth_len
);
525 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
526 auth_len
, src_addr
, type
, pos
) < 0)
532 bin_clear_free(plain
, plain_len
);
536 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
546 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
547 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
548 &f_##field##_len, &f_##field) < 0 || \
549 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
550 wpa_printf(MSG_INFO, "FT: Missing required " #field \
551 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
552 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
557 #define RRB_GET(type, field, txt, checklength) \
558 RRB_GET_SRC(plain, type, field, txt, checklength)
559 #define RRB_GET_AUTH(type, field, txt, checklength) \
560 RRB_GET_SRC(auth, type, field, txt, checklength)
562 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
563 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
564 &f_##field##_len, &f_##field) < 0 || \
565 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
566 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
567 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
568 f_##field##_len = 0; \
573 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
574 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
575 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
576 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
578 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
579 const u8
*data
, size_t data_len
)
581 if (wpa_auth
->cb
->send_ether
== NULL
)
583 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
584 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
589 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
590 const u8
*dst
, u8 oui_suffix
,
591 const u8
*data
, size_t data_len
)
593 if (!wpa_auth
->cb
->send_oui
)
595 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
,
596 oui_suffix
, MAC2STR(dst
));
597 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
602 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
603 const u8
*dst
, const u8
*data
, size_t data_len
)
605 if (wpa_auth
->cb
->send_ft_action
== NULL
)
607 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
612 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
613 const u8
*addr
, const u8
*p2p_dev_addr
,
616 if (wpa_auth
->cb
->get_psk
== NULL
)
618 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
623 static struct wpa_state_machine
*
624 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
626 if (wpa_auth
->cb
->add_sta
== NULL
)
628 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
632 static int wpa_ft_set_vlan(struct wpa_authenticator
*wpa_auth
,
633 const u8
*sta_addr
, struct vlan_description
*vlan
)
635 if (!wpa_auth
->cb
->set_vlan
)
637 return wpa_auth
->cb
->set_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
641 static int wpa_ft_get_vlan(struct wpa_authenticator
*wpa_auth
,
642 const u8
*sta_addr
, struct vlan_description
*vlan
)
644 if (!wpa_auth
->cb
->get_vlan
)
646 return wpa_auth
->cb
->get_vlan(wpa_auth
->cb_ctx
, sta_addr
, vlan
);
651 wpa_ft_set_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
652 const u8
*identity
, size_t identity_len
)
654 if (!wpa_auth
->cb
->set_identity
)
656 return wpa_auth
->cb
->set_identity(wpa_auth
->cb_ctx
, sta_addr
, identity
,
662 wpa_ft_get_identity(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
666 if (!wpa_auth
->cb
->get_identity
)
668 return wpa_auth
->cb
->get_identity(wpa_auth
->cb_ctx
, sta_addr
, buf
);
673 wpa_ft_set_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
674 const u8
*radius_cui
, size_t radius_cui_len
)
676 if (!wpa_auth
->cb
->set_radius_cui
)
678 return wpa_auth
->cb
->set_radius_cui(wpa_auth
->cb_ctx
, sta_addr
,
679 radius_cui
, radius_cui_len
);
684 wpa_ft_get_radius_cui(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
,
688 if (!wpa_auth
->cb
->get_radius_cui
)
690 return wpa_auth
->cb
->get_radius_cui(wpa_auth
->cb_ctx
, sta_addr
, buf
);
695 wpa_ft_set_session_timeout(struct wpa_authenticator
*wpa_auth
,
696 const u8
*sta_addr
, int session_timeout
)
698 if (!wpa_auth
->cb
->set_session_timeout
)
700 wpa_auth
->cb
->set_session_timeout(wpa_auth
->cb_ctx
, sta_addr
,
706 wpa_ft_get_session_timeout(struct wpa_authenticator
*wpa_auth
,
709 if (!wpa_auth
->cb
->get_session_timeout
)
711 return wpa_auth
->cb
->get_session_timeout(wpa_auth
->cb_ctx
, sta_addr
);
715 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
717 u8
*tspec_ie
, size_t tspec_ielen
)
719 if (wpa_auth
->cb
->add_tspec
== NULL
) {
720 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
723 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
728 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
732 if (len
< 2 + sizeof(struct rsn_mdie
))
735 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
736 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
737 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
738 pos
+= MOBILITY_DOMAIN_ID_LEN
;
740 if (conf
->ft_over_ds
)
741 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
748 int wpa_write_ftie(struct wpa_auth_config
*conf
, const u8
*r0kh_id
,
750 const u8
*anonce
, const u8
*snonce
,
751 u8
*buf
, size_t len
, const u8
*subelem
,
754 u8
*pos
= buf
, *ielen
;
755 struct rsn_ftie
*hdr
;
757 if (len
< 2 + sizeof(*hdr
) + 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
761 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
764 hdr
= (struct rsn_ftie
*) pos
;
765 os_memset(hdr
, 0, sizeof(*hdr
));
767 WPA_PUT_LE16(hdr
->mic_control
, 0);
769 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
771 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
773 /* Optional Parameters */
774 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
775 *pos
++ = FT_R1KH_ID_LEN
;
776 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
777 pos
+= FT_R1KH_ID_LEN
;
780 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
781 *pos
++ = r0kh_id_len
;
782 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
787 os_memcpy(pos
, subelem
, subelem_len
);
791 *ielen
= pos
- buf
- 2;
797 /* A packet to be handled after seq response */
798 struct ft_remote_item
{
801 u8 nonce
[FT_RRB_NONCE_LEN
];
802 struct os_reltime nonce_ts
;
804 u8 src_addr
[ETH_ALEN
];
809 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
811 const u8
*enc
, size_t enc_len
,
812 const u8
*auth
, size_t auth_len
,
817 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
819 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
820 dl_list_del(&item
->list
);
821 bin_clear_free(item
->enc
, item
->enc_len
);
827 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
828 struct ft_remote_seq
*rkh_seq
, int cb
)
830 struct ft_remote_item
*item
, *n
;
832 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
833 struct ft_remote_item
, list
) {
835 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
836 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
837 wpa_ft_rrb_seq_free(item
);
842 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
844 struct ft_remote_item
*item
= timeout_ctx
;
846 wpa_ft_rrb_seq_free(item
);
851 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
852 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
853 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
854 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
855 const u8
*enc
, size_t enc_len
,
856 const u8
*auth
, size_t auth_len
,
857 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
859 const u8
*enc
, size_t enc_len
,
860 const u8
*auth
, size_t auth_len
,
863 struct ft_remote_item
*item
= NULL
;
866 struct tlv_list seq_req_auth
[] = {
867 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
868 .data
= NULL
/* to be filled: item->nonce */ },
869 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
871 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
873 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
876 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
877 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
881 item
= os_zalloc(sizeof(*item
));
885 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
888 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
889 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
893 if (os_get_reltime(&item
->nonce_ts
) < 0)
896 if (enc
&& enc_len
> 0) {
897 item
->enc
= os_memdup(enc
, enc_len
);
898 item
->enc_len
= enc_len
;
903 if (auth
&& auth_len
> 0) {
904 item
->auth
= os_memdup(auth
, auth_len
);
905 item
->auth_len
= auth_len
;
910 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
913 seq_req_auth
[0].data
= item
->nonce
;
915 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
, NULL
,
916 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
917 &packet
, &packet_len
) < 0) {
918 item
= NULL
; /* some other seq resp might still accept this */
922 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
924 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
931 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
934 bin_clear_free(item
->enc
, item
->enc_len
);
942 #define FT_RRB_SEQ_OK 0
943 #define FT_RRB_SEQ_DROP 1
944 #define FT_RRB_SEQ_DEFER 2
947 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
948 const u8
*enc
, size_t enc_len
,
949 const u8
*auth
, size_t auth_len
,
950 const char *msgtype
, int no_defer
)
954 const struct ft_rrb_seq
*msg_both
;
955 u32 msg_seq
, msg_off
, rkh_off
;
956 struct os_reltime now
;
959 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
960 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
961 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
963 if (rkh_seq
->rx
.num_last
== 0) {
964 /* first packet from remote */
968 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
969 /* remote might have rebooted */
973 if (os_get_reltime(&now
) == 0) {
974 u32 msg_ts_now_remote
, msg_ts_off
;
975 struct os_reltime now_remote
;
977 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
978 msg_ts_now_remote
= now_remote
.sec
;
979 msg_ts_off
= le_to_host32(msg_both
->ts
) -
980 (msg_ts_now_remote
- ftRRBseqTimeout
);
981 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
985 msg_seq
= le_to_host32(msg_both
->seq
);
986 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
987 msg_off
= msg_seq
- rkh_off
;
988 if (msg_off
> 0xC0000000)
989 goto out
; /* too old message, drop it */
991 if (msg_off
<= 0x40000000) {
992 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
993 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
994 goto out
; /* duplicate message, drop it */
997 return FT_RRB_SEQ_OK
;
1004 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
1005 MACSTR
, msgtype
, MAC2STR(src_addr
));
1007 return FT_RRB_SEQ_DEFER
;
1009 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
1010 msgtype
, MAC2STR(src_addr
));
1012 return FT_RRB_SEQ_DROP
;
1017 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
1018 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
1019 const u8
*auth
, size_t auth_len
,
1020 const char *msgtype
)
1024 const struct ft_rrb_seq
*msg_both
;
1025 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
1029 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
1030 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
1032 msg_seq
= le_to_host32(msg_both
->seq
);
1034 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
1035 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
1036 rkh_seq
->rx
.num_last
++;
1040 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
1041 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
1042 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
1043 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
1044 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
1047 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
1048 rkh_seq
->rx
.offsetidx
= minidx
;
1052 /* RRB_GET_AUTH should never fail here as
1053 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
1054 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
1058 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
1059 struct ft_rrb_seq
*f_seq
)
1061 struct os_reltime now
;
1063 if (os_get_reltime(&now
) < 0)
1066 if (!rkh_seq
->tx
.dom
) {
1067 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
1068 sizeof(rkh_seq
->tx
.seq
))) {
1069 wpa_printf(MSG_ERROR
,
1070 "FT: Failed to get random data for sequence number initialization");
1071 rkh_seq
->tx
.seq
= now
.usec
;
1073 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
1074 sizeof(rkh_seq
->tx
.dom
))) {
1075 wpa_printf(MSG_ERROR
,
1076 "FT: Failed to get random data for sequence number initialization");
1077 rkh_seq
->tx
.dom
= now
.usec
;
1079 rkh_seq
->tx
.dom
|= 1;
1082 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
1083 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
1084 f_seq
->ts
= host_to_le32(now
.sec
);
1092 struct wpa_ft_pmk_r0_sa
{
1093 struct dl_list list
;
1095 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
1097 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1098 struct vlan_description
*vlan
;
1099 os_time_t expiration
; /* 0 for no expiration */
1101 size_t identity_len
;
1103 size_t radius_cui_len
;
1104 os_time_t session_timeout
; /* 0 for no expiration */
1105 /* TODO: radius_class, EAP type */
1109 struct wpa_ft_pmk_r1_sa
{
1110 struct dl_list list
;
1112 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
1114 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
1115 struct vlan_description
*vlan
;
1117 size_t identity_len
;
1119 size_t radius_cui_len
;
1120 os_time_t session_timeout
; /* 0 for no expiration */
1121 /* TODO: radius_class, EAP type */
1124 struct wpa_ft_pmk_cache
{
1125 struct dl_list pmk_r0
; /* struct wpa_ft_pmk_r0_sa */
1126 struct dl_list pmk_r1
; /* struct wpa_ft_pmk_r1_sa */
1130 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
);
1131 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
);
1134 static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa
*r0
)
1139 dl_list_del(&r0
->list
);
1140 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1142 os_memset(r0
->pmk_r0
, 0, PMK_LEN
);
1144 os_free(r0
->identity
);
1145 os_free(r0
->radius_cui
);
1150 static void wpa_ft_expire_pmk_r0(void *eloop_ctx
, void *timeout_ctx
)
1152 struct wpa_ft_pmk_r0_sa
*r0
= eloop_ctx
;
1153 struct os_reltime now
;
1155 int session_timeout
;
1157 os_get_reltime(&now
);
1162 expires_in
= r0
->expiration
- now
.sec
;
1163 session_timeout
= r0
->session_timeout
- now
.sec
;
1164 /* conditions to remove from cache:
1165 * a) r0->expiration is set and hit
1167 * b) r0->session_timeout is set and hit
1169 if ((!r0
->expiration
|| expires_in
> 0) &&
1170 (!r0
->session_timeout
|| session_timeout
> 0)) {
1171 wpa_printf(MSG_ERROR
,
1172 "FT: %s() called for non-expired entry %p",
1174 eloop_cancel_timeout(wpa_ft_expire_pmk_r0
, r0
, NULL
);
1175 if (r0
->expiration
&& expires_in
> 0)
1176 eloop_register_timeout(expires_in
+ 1, 0,
1177 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1178 if (r0
->session_timeout
&& session_timeout
> 0)
1179 eloop_register_timeout(session_timeout
+ 1, 0,
1180 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1184 wpa_ft_free_pmk_r0(r0
);
1188 static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa
*r1
)
1193 dl_list_del(&r1
->list
);
1194 eloop_cancel_timeout(wpa_ft_expire_pmk_r1
, r1
, NULL
);
1196 os_memset(r1
->pmk_r1
, 0, PMK_LEN
);
1198 os_free(r1
->identity
);
1199 os_free(r1
->radius_cui
);
1204 static void wpa_ft_expire_pmk_r1(void *eloop_ctx
, void *timeout_ctx
)
1206 struct wpa_ft_pmk_r1_sa
*r1
= eloop_ctx
;
1208 wpa_ft_free_pmk_r1(r1
);
1212 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
1214 struct wpa_ft_pmk_cache
*cache
;
1216 cache
= os_zalloc(sizeof(*cache
));
1218 dl_list_init(&cache
->pmk_r0
);
1219 dl_list_init(&cache
->pmk_r1
);
1226 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
1228 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
1229 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
1231 dl_list_for_each_safe(r0
, r0prev
, &cache
->pmk_r0
,
1232 struct wpa_ft_pmk_r0_sa
, list
)
1233 wpa_ft_free_pmk_r0(r0
);
1235 dl_list_for_each_safe(r1
, r1prev
, &cache
->pmk_r1
,
1236 struct wpa_ft_pmk_r1_sa
, list
)
1237 wpa_ft_free_pmk_r1(r1
);
1243 static int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1244 const u8
*spa
, const u8
*pmk_r0
,
1245 const u8
*pmk_r0_name
, int pairwise
,
1246 const struct vlan_description
*vlan
,
1247 int expires_in
, int session_timeout
,
1248 const u8
*identity
, size_t identity_len
,
1249 const u8
*radius_cui
, size_t radius_cui_len
)
1251 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1252 struct wpa_ft_pmk_r0_sa
*r0
;
1253 struct os_reltime now
;
1255 /* TODO: add limit on number of entries in cache */
1256 os_get_reltime(&now
);
1258 r0
= os_zalloc(sizeof(*r0
));
1262 os_memcpy(r0
->pmk_r0
, pmk_r0
, PMK_LEN
);
1263 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
1264 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
1265 r0
->pairwise
= pairwise
;
1267 r0
->expiration
= now
.sec
+ expires_in
;
1268 if (vlan
&& vlan
->notempty
) {
1269 r0
->vlan
= os_zalloc(sizeof(*vlan
));
1271 bin_clear_free(r0
, sizeof(*r0
));
1277 r0
->identity
= os_malloc(identity_len
);
1279 os_memcpy(r0
->identity
, identity
, identity_len
);
1280 r0
->identity_len
= identity_len
;
1284 r0
->radius_cui
= os_malloc(radius_cui_len
);
1285 if (r0
->radius_cui
) {
1286 os_memcpy(r0
->radius_cui
, radius_cui
, radius_cui_len
);
1287 r0
->radius_cui_len
= radius_cui_len
;
1290 if (session_timeout
> 0)
1291 r0
->session_timeout
= now
.sec
+ session_timeout
;
1293 dl_list_add(&cache
->pmk_r0
, &r0
->list
);
1295 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r0
,
1297 if (session_timeout
> 0)
1298 eloop_register_timeout(session_timeout
+ 1, 0,
1299 wpa_ft_expire_pmk_r0
, r0
, NULL
);
1305 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
1306 const u8
*spa
, const u8
*pmk_r0_name
,
1307 const struct wpa_ft_pmk_r0_sa
**r0_out
)
1309 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1310 struct wpa_ft_pmk_r0_sa
*r0
;
1311 struct os_reltime now
;
1313 os_get_reltime(&now
);
1314 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
1315 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
1316 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
1317 WPA_PMK_NAME_LEN
) == 0) {
1328 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1329 const u8
*spa
, const u8
*pmk_r1
,
1330 const u8
*pmk_r1_name
, int pairwise
,
1331 const struct vlan_description
*vlan
,
1332 int expires_in
, int session_timeout
,
1333 const u8
*identity
, size_t identity_len
,
1334 const u8
*radius_cui
, size_t radius_cui_len
)
1336 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1337 int max_expires_in
= wpa_auth
->conf
.r1_max_key_lifetime
;
1338 struct wpa_ft_pmk_r1_sa
*r1
;
1339 struct os_reltime now
;
1341 /* TODO: limit on number of entries in cache */
1342 os_get_reltime(&now
);
1344 if (max_expires_in
&& (max_expires_in
< expires_in
|| expires_in
== 0))
1345 expires_in
= max_expires_in
;
1347 r1
= os_zalloc(sizeof(*r1
));
1351 os_memcpy(r1
->pmk_r1
, pmk_r1
, PMK_LEN
);
1352 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
1353 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
1354 r1
->pairwise
= pairwise
;
1355 if (vlan
&& vlan
->notempty
) {
1356 r1
->vlan
= os_zalloc(sizeof(*vlan
));
1358 bin_clear_free(r1
, sizeof(*r1
));
1364 r1
->identity
= os_malloc(identity_len
);
1366 os_memcpy(r1
->identity
, identity
, identity_len
);
1367 r1
->identity_len
= identity_len
;
1371 r1
->radius_cui
= os_malloc(radius_cui_len
);
1372 if (r1
->radius_cui
) {
1373 os_memcpy(r1
->radius_cui
, radius_cui
, radius_cui_len
);
1374 r1
->radius_cui_len
= radius_cui_len
;
1377 if (session_timeout
> 0)
1378 r1
->session_timeout
= now
.sec
+ session_timeout
;
1380 dl_list_add(&cache
->pmk_r1
, &r1
->list
);
1383 eloop_register_timeout(expires_in
+ 1, 0, wpa_ft_expire_pmk_r1
,
1385 if (session_timeout
> 0)
1386 eloop_register_timeout(session_timeout
+ 1, 0,
1387 wpa_ft_expire_pmk_r1
, r1
, NULL
);
1393 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
1394 const u8
*spa
, const u8
*pmk_r1_name
,
1395 u8
*pmk_r1
, int *pairwise
,
1396 struct vlan_description
*vlan
,
1397 const u8
**identity
, size_t *identity_len
,
1398 const u8
**radius_cui
, size_t *radius_cui_len
,
1399 int *session_timeout
)
1401 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
1402 struct wpa_ft_pmk_r1_sa
*r1
;
1403 struct os_reltime now
;
1405 os_get_reltime(&now
);
1407 dl_list_for_each(r1
, &cache
->pmk_r1
, struct wpa_ft_pmk_r1_sa
, list
) {
1408 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
1409 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
1410 WPA_PMK_NAME_LEN
) == 0) {
1411 os_memcpy(pmk_r1
, r1
->pmk_r1
, PMK_LEN
);
1413 *pairwise
= r1
->pairwise
;
1414 if (vlan
&& r1
->vlan
)
1416 if (vlan
&& !r1
->vlan
)
1417 os_memset(vlan
, 0, sizeof(*vlan
));
1418 if (identity
&& identity_len
) {
1419 *identity
= r1
->identity
;
1420 *identity_len
= r1
->identity_len
;
1422 if (radius_cui
&& radius_cui_len
) {
1423 *radius_cui
= r1
->radius_cui
;
1424 *radius_cui_len
= r1
->radius_cui_len
;
1426 if (session_timeout
&& r1
->session_timeout
> now
.sec
)
1427 *session_timeout
= r1
->session_timeout
-
1429 else if (session_timeout
&& r1
->session_timeout
)
1430 *session_timeout
= 1;
1432 *session_timeout
= 0;
1441 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
1446 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1448 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1452 dl_list_init(&r0kh
->seq
->rx
.queue
);
1458 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1459 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1460 struct ft_remote_r0kh
**r0kh_out
,
1461 struct ft_remote_r0kh
**r0kh_wildcard
)
1463 struct ft_remote_r0kh
*r0kh
;
1465 *r0kh_wildcard
= NULL
;
1468 if (wpa_auth
->conf
.r0kh_list
)
1469 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1472 for (; r0kh
; r0kh
= r0kh
->next
) {
1473 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1474 *r0kh_wildcard
= r0kh
;
1475 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1476 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1480 if (!*r0kh_out
&& !*r0kh_wildcard
)
1481 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1483 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1488 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1493 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1495 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1499 dl_list_init(&r1kh
->seq
->rx
.queue
);
1505 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1506 const u8
*f_r1kh_id
,
1507 struct ft_remote_r1kh
**r1kh_out
,
1508 struct ft_remote_r1kh
**r1kh_wildcard
)
1510 struct ft_remote_r1kh
*r1kh
;
1512 *r1kh_wildcard
= NULL
;
1515 if (wpa_auth
->conf
.r1kh_list
)
1516 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1519 for (; r1kh
; r1kh
= r1kh
->next
) {
1520 if (is_zero_ether_addr(r1kh
->addr
) &&
1521 is_zero_ether_addr(r1kh
->id
))
1522 *r1kh_wildcard
= r1kh
;
1524 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1528 if (!*r1kh_out
&& !*r1kh_wildcard
)
1529 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1531 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1536 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1537 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1539 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1540 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1541 f_r0kh_id_len
) != 0)
1548 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1549 const u8
*f_r1kh_id
)
1551 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1552 FT_R1KH_ID_LEN
) != 0)
1559 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1561 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1562 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1564 if (!wpa_auth
->conf
.r0kh_list
)
1567 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1568 if (r0kh
== timeout_ctx
)
1575 prev
->next
= r0kh
->next
;
1577 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1579 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1585 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1586 struct ft_remote_r0kh
*r0kh
, int timeout
)
1589 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1594 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1595 struct ft_remote_r0kh
*r0kh
, int timeout
)
1597 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1600 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1605 static struct ft_remote_r0kh
*
1606 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1607 struct ft_remote_r0kh
*r0kh_wildcard
,
1608 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1611 struct ft_remote_r0kh
*r0kh
;
1613 if (!wpa_auth
->conf
.r0kh_list
)
1616 r0kh
= os_zalloc(sizeof(*r0kh
));
1621 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1623 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1624 id_len
= FT_R0KH_ID_MAX_LEN
;
1625 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1626 r0kh
->id_len
= id_len
;
1628 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1630 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1631 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1634 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1637 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1644 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1646 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1647 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1649 if (!wpa_auth
->conf
.r1kh_list
)
1652 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1653 if (r1kh
== timeout_ctx
)
1660 prev
->next
= r1kh
->next
;
1662 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1664 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1670 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1671 struct ft_remote_r1kh
*r1kh
, int timeout
)
1674 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1679 static struct ft_remote_r1kh
*
1680 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1681 struct ft_remote_r1kh
*r1kh_wildcard
,
1682 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1684 struct ft_remote_r1kh
*r1kh
;
1686 if (!wpa_auth
->conf
.r1kh_list
)
1689 r1kh
= os_zalloc(sizeof(*r1kh
));
1693 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1694 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1695 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1696 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1697 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1700 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1703 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1710 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1712 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1716 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1718 struct ft_remote_r0kh
*r0kh
;
1719 struct ft_remote_r1kh
*r1kh
;
1721 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1723 if (wpa_auth
->conf
.r0kh_list
)
1724 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1727 for (; r0kh
; r0kh
= r0kh
->next
) {
1730 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1735 if (wpa_auth
->conf
.r1kh_list
)
1736 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1739 for (; r1kh
; r1kh
= r1kh
->next
) {
1742 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1749 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1751 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1752 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1754 if (wpa_auth
->conf
.r0kh_list
)
1755 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1759 r0kh_next
= r0kh
->next
;
1760 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1763 r0kh_prev
->next
= r0kh_next
;
1765 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1773 if (wpa_auth
->conf
.r1kh_list
)
1774 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1778 r1kh_next
= r1kh
->next
;
1779 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1782 r1kh_prev
->next
= r1kh_next
;
1784 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1794 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1796 wpa_ft_deinit_seq(wpa_auth
);
1797 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1801 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1802 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1804 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1806 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1809 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1810 &r0kh
, &r0kh_wildcard
);
1812 if (!r0kh_wildcard
) {
1813 /* r0kh removed after neg_timeout and might need re-adding */
1817 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1818 f_r0kh_id
, f_r0kh_id_len
);
1821 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1822 wpa_auth
->conf
.rkh_neg_timeout
);
1823 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1825 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1827 wpa_auth
->conf
.rkh_neg_timeout
);
1831 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1833 struct wpa_state_machine
*sm
= eloop_ctx
;
1835 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1837 if (sm
->ft_pending_pull_left_retries
<= 0)
1838 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1840 /* cancel multiple timeouts */
1841 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1846 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1847 const u8
*ies
, size_t ies_len
,
1848 const u8
*pmk_r0_name
)
1850 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1852 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1853 size_t packet_len
, key_len
;
1854 struct ft_rrb_seq f_seq
;
1855 int tsecs
, tusecs
, first
;
1856 struct wpabuf
*ft_pending_req_ies
;
1858 struct tlv_list req_enc
[] = {
1859 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1860 .data
= pmk_r0_name
},
1861 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1863 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1865 struct tlv_list req_auth
[] = {
1866 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1867 .data
= sm
->ft_pending_pull_nonce
},
1868 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1869 .data
= (u8
*) &f_seq
},
1870 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1871 .data
= sm
->r0kh_id
},
1872 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1873 .data
= f_r1kh_id
},
1874 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1877 if (sm
->ft_pending_pull_left_retries
<= 0)
1879 first
= sm
->ft_pending_pull_left_retries
==
1880 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1881 sm
->ft_pending_pull_left_retries
--;
1883 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1884 &r0kh
, &r0kh_wildcard
);
1886 /* Keep r0kh sufficiently long in the list for seq num check */
1887 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1888 1 + ftRRBseqTimeout
;
1890 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1891 } else if (r0kh_wildcard
) {
1892 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1893 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1894 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1895 r0kh_wildcard
->addr
,
1896 sm
->r0kh_id
, sm
->r0kh_id_len
,
1900 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1901 sm
->r0kh_id
, sm
->r0kh_id_len
);
1904 if (is_zero_ether_addr(r0kh
->addr
)) {
1905 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1906 sm
->r0kh_id
, sm
->r0kh_id_len
);
1909 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1910 wpa_printf(MSG_DEBUG
,
1911 "FT: R0KH-ID points to self - no matching key available");
1916 key_len
= sizeof(r0kh
->key
);
1918 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
1919 "address " MACSTR
, MAC2STR(r0kh
->addr
));
1921 if (r0kh
->seq
->rx
.num_last
== 0) {
1922 /* A sequence request will be sent out anyway when pull
1923 * response is received. Send it out now to avoid one RTT. */
1924 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
1925 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
1926 key_len
, NULL
, 0, NULL
, 0, NULL
);
1930 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
1931 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
1936 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
1937 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
1941 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
, NULL
,
1942 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1943 &packet
, &packet_len
) < 0)
1946 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
1947 wpabuf_free(sm
->ft_pending_req_ies
);
1948 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
1949 if (!sm
->ft_pending_req_ies
) {
1954 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
1955 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
1956 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
1958 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1959 packet
, packet_len
);
1967 int wpa_ft_store_pmk_fils(struct wpa_state_machine
*sm
,
1968 const u8
*pmk_r0
, const u8
*pmk_r0_name
)
1970 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
1971 struct vlan_description vlan
;
1972 const u8
*identity
, *radius_cui
;
1973 size_t identity_len
, radius_cui_len
;
1974 int session_timeout
;
1976 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
1977 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
1982 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
1983 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
1985 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
1987 return wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_name
,
1988 sm
->pairwise
, &vlan
, expires_in
,
1989 session_timeout
, identity
, identity_len
,
1990 radius_cui
, radius_cui_len
);
1994 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, const u8
*pmk
,
1995 struct wpa_ptk
*ptk
)
1997 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
1999 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2000 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
2001 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
2002 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
2003 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
2004 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
2005 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
2006 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
2007 int expires_in
= sm
->wpa_auth
->conf
.r0_key_lifetime
;
2008 struct vlan_description vlan
;
2009 const u8
*identity
, *radius_cui
;
2010 size_t identity_len
, radius_cui_len
;
2011 int session_timeout
;
2013 if (sm
->xxkey_len
== 0) {
2014 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
2019 if (wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2020 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA " MACSTR
,
2025 identity_len
= wpa_ft_get_identity(sm
->wpa_auth
, sm
->addr
, &identity
);
2026 radius_cui_len
= wpa_ft_get_radius_cui(sm
->wpa_auth
, sm
->addr
,
2028 session_timeout
= wpa_ft_get_session_timeout(sm
->wpa_auth
, sm
->addr
);
2030 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
2031 r0kh
, r0kh_len
, sm
->addr
,
2032 pmk_r0
, pmk_r0_name
) < 0)
2034 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, PMK_LEN
);
2035 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
2036 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2037 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_name
,
2038 sm
->pairwise
, &vlan
, expires_in
,
2039 session_timeout
, identity
, identity_len
,
2040 radius_cui
, radius_cui_len
);
2042 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
2043 pmk_r1
, sm
->pmk_r1_name
) < 0)
2045 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
2046 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
2048 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
2049 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
,
2050 sm
->pmk_r1_name
, sm
->pairwise
, &vlan
,
2051 expires_in
, session_timeout
, identity
,
2052 identity_len
, radius_cui
, radius_cui_len
);
2054 return wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
2055 sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
2056 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
2060 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
2061 const u8
*addr
, int idx
, u8
*seq
)
2063 if (wpa_auth
->cb
->get_seqnum
== NULL
)
2065 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
2069 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2072 struct wpa_group
*gsm
= sm
->group
;
2073 size_t subelem_len
, pad_len
;
2078 key_len
= gsm
->GTK_len
;
2079 if (key_len
> sizeof(keybuf
))
2083 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
2086 pad_len
= key_len
% 8;
2088 pad_len
= 8 - pad_len
;
2089 if (key_len
+ pad_len
< 16)
2091 if (pad_len
&& key_len
< sizeof(keybuf
)) {
2092 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
2093 os_memset(keybuf
+ key_len
, 0, pad_len
);
2094 keybuf
[key_len
] = 0xdd;
2098 key
= gsm
->GTK
[gsm
->GN
- 1];
2101 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
2104 subelem_len
= 13 + key_len
+ 8;
2105 subelem
= os_zalloc(subelem_len
);
2106 if (subelem
== NULL
)
2109 subelem
[0] = FTIE_SUBELEM_GTK
;
2110 subelem
[1] = 11 + key_len
+ 8;
2111 /* Key ID in B0-B1 of Key Info */
2112 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
2113 subelem
[4] = gsm
->GTK_len
;
2114 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
2115 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, key_len
/ 8, key
,
2126 #ifdef CONFIG_IEEE80211W
2127 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
2130 struct wpa_group
*gsm
= sm
->group
;
2133 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
2135 subelem_len
= 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN
+ 8;
2136 subelem
= os_zalloc(subelem_len
);
2137 if (subelem
== NULL
)
2141 *pos
++ = FTIE_SUBELEM_IGTK
;
2142 *pos
++ = subelem_len
- 2;
2143 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
2145 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
2147 *pos
++ = WPA_IGTK_LEN
;
2148 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, WPA_IGTK_LEN
/ 8,
2149 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
2157 #endif /* CONFIG_IEEE80211W */
2160 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
2161 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
2162 const u8
*ies
, size_t ies_len
)
2164 struct ieee802_11_elems parse
;
2165 struct rsn_rdie
*rdie
;
2167 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
2169 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
2172 if (end
- pos
< (int) sizeof(*rdie
)) {
2173 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
2177 *pos
++ = WLAN_EID_RIC_DATA
;
2178 *pos
++ = sizeof(*rdie
);
2179 rdie
= (struct rsn_rdie
*) pos
;
2181 rdie
->descr_count
= 0;
2182 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
2183 pos
+= sizeof(*rdie
);
2185 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
2187 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
2189 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2193 if (parse
.wmm_tspec
) {
2194 struct wmm_tspec_element
*tspec
;
2196 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
2197 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
2198 "(%d)", (int) parse
.wmm_tspec_len
);
2200 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2203 if (end
- pos
< (int) sizeof(*tspec
)) {
2204 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
2207 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2210 tspec
= (struct wmm_tspec_element
*) pos
;
2211 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
2215 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
2218 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
2219 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
2220 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
2222 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
2223 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
2225 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
2227 /* TSPEC accepted; include updated TSPEC in response */
2228 rdie
->descr_count
= 1;
2229 pos
+= sizeof(struct wmm_tspec_element
);
2233 #endif /* NEED_AP_MLME */
2235 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
2238 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
2239 sizeof(struct wmm_tspec_element
));
2242 rdie
->status_code
= host_to_le16(res
);
2244 /* TSPEC accepted; include updated TSPEC in
2246 rdie
->descr_count
= 1;
2247 pos
+= sizeof(struct wmm_tspec_element
);
2253 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
2254 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
2259 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
2260 const u8
*ric
, size_t ric_len
)
2262 const u8
*rpos
, *start
;
2263 const struct rsn_rdie
*rdie
;
2265 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
2268 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
2269 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
2270 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
2272 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
2273 rpos
+= 2 + rpos
[1];
2276 while (rpos
+ 2 <= ric
+ ric_len
&&
2277 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
2278 if (rpos
[0] == WLAN_EID_RIC_DATA
)
2280 rpos
+= 2 + rpos
[1];
2282 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
2284 start
, rpos
- start
);
2291 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
2292 size_t max_len
, int auth_alg
,
2293 const u8
*req_ies
, size_t req_ies_len
)
2295 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
2296 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
2298 struct wpa_auth_config
*conf
;
2299 struct rsn_ftie
*_ftie
;
2300 struct wpa_ft_ies parse
;
2302 u8
*anonce
, *snonce
;
2309 conf
= &sm
->wpa_auth
->conf
;
2311 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
2314 end
= pos
+ max_len
;
2316 if (auth_alg
== WLAN_AUTH_FT
) {
2318 * RSN (only present if this is a Reassociation Response and
2319 * part of a fast BSS transition)
2321 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
2329 /* Mobility Domain Information */
2330 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
2337 /* Fast BSS Transition Information */
2338 if (auth_alg
== WLAN_AUTH_FT
) {
2339 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
2340 r0kh_id
= sm
->r0kh_id
;
2341 r0kh_id_len
= sm
->r0kh_id_len
;
2342 anonce
= sm
->ANonce
;
2343 snonce
= sm
->SNonce
;
2344 #ifdef CONFIG_IEEE80211W
2345 if (sm
->mgmt_frame_prot
) {
2349 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
2354 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
2361 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
2362 subelem_len
+= igtk_len
;
2365 #endif /* CONFIG_IEEE80211W */
2367 r0kh_id
= conf
->r0_key_holder
;
2368 r0kh_id_len
= conf
->r0_key_holder_len
;
2372 res
= wpa_write_ftie(conf
, r0kh_id
, r0kh_id_len
, anonce
, snonce
, pos
,
2373 end
- pos
, subelem
, subelem_len
);
2381 _ftie
= (struct rsn_ftie
*) (ftie
+ 2);
2382 if (auth_alg
== WLAN_AUTH_FT
)
2383 _ftie
->mic_control
[1] = 3; /* Information element count */
2386 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
) == 0 && parse
.ric
) {
2387 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
2389 if (auth_alg
== WLAN_AUTH_FT
)
2390 _ftie
->mic_control
[1] +=
2391 ieee802_11_ie_count(ric_start
,
2394 if (ric_start
== pos
)
2397 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2399 kck_len
= sm
->PTK
.kck2_len
;
2402 kck_len
= sm
->PTK
.kck_len
;
2404 if (auth_alg
== WLAN_AUTH_FT
&&
2405 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
2406 mdie
, mdie_len
, ftie
, ftie_len
,
2408 ric_start
, ric_start
? pos
- ric_start
: 0,
2410 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2412 os_free(sm
->assoc_resp_ftie
);
2413 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
2414 if (sm
->assoc_resp_ftie
)
2415 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
2421 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
2423 enum wpa_alg alg
, const u8
*addr
, int idx
,
2424 u8
*key
, size_t key_len
)
2426 if (wpa_auth
->cb
->set_key
== NULL
)
2428 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
2433 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
2438 /* MLME-SETKEYS.request(PTK) */
2439 alg
= wpa_cipher_to_alg(sm
->pairwise
);
2440 klen
= wpa_cipher_key_len(sm
->pairwise
);
2441 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
2442 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
2443 "PTK configuration", sm
->pairwise
);
2447 if (sm
->tk_already_set
) {
2448 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
2449 * PN in the driver */
2450 wpa_printf(MSG_DEBUG
,
2451 "FT: Do not re-install same PTK to the driver");
2455 /* FIX: add STA entry to kernel/driver here? The set_key will fail
2456 * most likely without this.. At the moment, STA entry is added only
2457 * after association has been completed. This function will be called
2458 * again after association to get the PTK configured, but that could be
2459 * optimized by adding the STA entry earlier.
2461 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
2465 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
2466 sm
->pairwise_set
= TRUE
;
2467 sm
->tk_already_set
= TRUE
;
2471 /* Derive PMK-R1 from PSK, check all available PSK */
2472 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
2473 const u8
*req_pmk_r1_name
,
2474 u8
*out_pmk_r1
, int *out_pairwise
,
2475 struct vlan_description
*out_vlan
,
2476 const u8
**out_identity
, size_t *out_identity_len
,
2477 const u8
**out_radius_cui
,
2478 size_t *out_radius_cui_len
,
2479 int *out_session_timeout
)
2481 const u8
*pmk
= NULL
;
2482 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
2483 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2484 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2485 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
2486 const u8
*r0kh
= sm
->r0kh_id
;
2487 size_t r0kh_len
= sm
->r0kh_id_len
;
2488 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
2489 const u8
*ssid
= wpa_auth
->conf
.ssid
;
2490 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
2493 pairwise
= sm
->pairwise
;
2496 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2501 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2503 pmk_r0
, pmk_r0_name
) < 0 ||
2504 wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
2505 pmk_r1
, pmk_r1_name
) < 0 ||
2506 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2507 WPA_PMK_NAME_LEN
) != 0)
2510 /* We found a PSK that matches the requested pmk_r1_name */
2511 wpa_printf(MSG_DEBUG
,
2512 "FT: Found PSK to generate PMK-R1 locally");
2513 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2515 *out_pairwise
= pairwise
;
2517 wpa_ft_get_vlan(sm
->wpa_auth
, sm
->addr
, out_vlan
) < 0) {
2518 wpa_printf(MSG_DEBUG
, "FT: vlan not available for STA "
2519 MACSTR
, MAC2STR(sm
->addr
));
2523 if (out_identity
&& out_identity_len
) {
2524 *out_identity_len
= wpa_ft_get_identity(
2525 sm
->wpa_auth
, sm
->addr
, out_identity
);
2528 if (out_radius_cui
&& out_radius_cui_len
) {
2529 *out_radius_cui_len
= wpa_ft_get_radius_cui(
2530 sm
->wpa_auth
, sm
->addr
, out_radius_cui
);
2533 if (out_session_timeout
) {
2534 *out_session_timeout
= wpa_ft_get_session_timeout(
2535 sm
->wpa_auth
, sm
->addr
);
2541 wpa_printf(MSG_DEBUG
,
2542 "FT: Did not find PSK to generate PMK-R1 locally");
2547 /* Detect the configuration the station asked for.
2548 * Required to detect FT-PSK and pairwise cipher.
2550 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2551 struct wpa_ft_ies
*parse
)
2553 int key_mgmt
, ciphers
;
2555 if (sm
->wpa_key_mgmt
)
2558 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2560 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2561 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2564 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2565 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2566 #ifdef CONFIG_SHA384
2567 else if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X_SHA384
)
2568 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X_SHA384
;
2569 #endif /* CONFIG_SHA384 */
2570 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2571 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2573 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2574 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2575 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2576 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2577 #endif /* CONFIG_FILS */
2578 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2580 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2582 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2585 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2591 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2592 struct wpa_state_machine
*sm
,
2593 const u8
*r0kh_id
, size_t r0kh_id_len
,
2594 const u8
*req_pmk_r0_name
,
2595 const u8
*req_pmk_r1_name
,
2596 u8
*out_pmk_r1
, int *out_pairwise
,
2597 struct vlan_description
*vlan
,
2598 const u8
**identity
, size_t *identity_len
,
2599 const u8
**radius_cui
,
2600 size_t *radius_cui_len
,
2601 int *out_session_timeout
)
2603 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2604 const struct wpa_ft_pmk_r0_sa
*r0
;
2605 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2607 int session_timeout
= 0;
2608 struct os_reltime now
;
2610 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2611 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2613 return -1; /* not our R0KH-ID */
2615 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2616 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2618 return -1; /* no matching PMKR0Name in local cache */
2620 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2622 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_name
, conf
->r1_key_holder
,
2623 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2625 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, PMK_LEN
);
2626 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2628 os_get_reltime(&now
);
2630 expires_in
= r0
->expiration
- now
.sec
;
2632 if (r0
->session_timeout
)
2633 session_timeout
= r0
->session_timeout
- now
.sec
;
2635 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, pmk_r1_name
,
2636 sm
->pairwise
, r0
->vlan
, expires_in
, session_timeout
,
2637 r0
->identity
, r0
->identity_len
,
2638 r0
->radius_cui
, r0
->radius_cui_len
);
2640 *out_pairwise
= sm
->pairwise
;
2645 os_memset(vlan
, 0, sizeof(*vlan
));
2648 if (identity
&& identity_len
) {
2649 *identity
= r0
->identity
;
2650 *identity_len
= r0
->identity_len
;
2653 if (radius_cui
&& radius_cui_len
) {
2654 *radius_cui
= r0
->radius_cui
;
2655 *radius_cui_len
= r0
->radius_cui_len
;
2658 *out_session_timeout
= session_timeout
;
2664 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2665 const u8
*ies
, size_t ies_len
,
2666 u8
**resp_ies
, size_t *resp_ies_len
)
2668 struct rsn_mdie
*mdie
;
2669 struct rsn_ftie
*ftie
;
2670 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2671 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2672 struct wpa_auth_config
*conf
;
2673 struct wpa_ft_ies parse
;
2677 int pairwise
, session_timeout
= 0;
2678 struct vlan_description vlan
;
2679 const u8
*identity
, *radius_cui
;
2680 size_t identity_len
= 0, radius_cui_len
= 0;
2685 sm
->pmk_r1_name_valid
= 0;
2686 conf
= &sm
->wpa_auth
->conf
;
2688 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2691 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2692 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2693 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2696 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2697 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2698 os_memcmp(mdie
->mobility_domain
,
2699 sm
->wpa_auth
->conf
.mobility_domain
,
2700 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2701 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2702 return WLAN_STATUS_INVALID_MDIE
;
2705 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2706 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2707 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2708 return WLAN_STATUS_INVALID_FTIE
;
2711 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2713 if (parse
.r0kh_id
== NULL
) {
2714 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2715 return WLAN_STATUS_INVALID_FTIE
;
2718 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2719 parse
.r0kh_id
, parse
.r0kh_id_len
);
2720 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2721 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2723 if (parse
.rsn_pmkid
== NULL
) {
2724 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2725 return WLAN_STATUS_INVALID_PMKID
;
2728 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2729 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2731 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2732 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2733 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2734 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2736 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2737 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2738 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2740 if (conf
->ft_psk_generate_local
&&
2741 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2742 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
,
2743 &vlan
, &identity
, &identity_len
,
2744 &radius_cui
, &radius_cui_len
,
2745 &session_timeout
) < 0)
2746 return WLAN_STATUS_INVALID_PMKID
;
2747 wpa_printf(MSG_DEBUG
,
2748 "FT: Generated PMK-R1 for FT-PSK locally");
2749 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2750 pmk_r1
, &pairwise
, &vlan
, &identity
,
2751 &identity_len
, &radius_cui
,
2752 &radius_cui_len
, &session_timeout
) < 0) {
2753 wpa_printf(MSG_DEBUG
,
2754 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2755 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2756 parse
.r0kh_id
, parse
.r0kh_id_len
,
2758 pmk_r1_name
, pmk_r1
, &pairwise
,
2759 &vlan
, &identity
, &identity_len
,
2760 &radius_cui
, &radius_cui_len
,
2761 &session_timeout
) == 0) {
2762 wpa_printf(MSG_DEBUG
,
2763 "FT: Generated PMK-R1 based on local PMK-R0");
2764 goto pmk_r1_derived
;
2767 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2768 wpa_printf(MSG_DEBUG
,
2769 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2770 return WLAN_STATUS_INVALID_PMKID
;
2773 return -1; /* Status pending */
2775 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2779 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, PMK_LEN
);
2780 sm
->pmk_r1_name_valid
= 1;
2781 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2783 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2784 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2786 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2789 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2790 sm
->SNonce
, WPA_NONCE_LEN
);
2791 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2792 sm
->ANonce
, WPA_NONCE_LEN
);
2794 if (wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
2795 sm
->wpa_auth
->addr
, pmk_r1_name
,
2796 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
2798 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2800 sm
->pairwise
= pairwise
;
2801 sm
->PTK_valid
= TRUE
;
2802 sm
->tk_already_set
= FALSE
;
2803 wpa_ft_install_ptk(sm
);
2805 if (wpa_ft_set_vlan(sm
->wpa_auth
, sm
->addr
, &vlan
) < 0) {
2806 wpa_printf(MSG_DEBUG
, "FT: Failed to configure VLAN");
2807 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2809 if (wpa_ft_set_identity(sm
->wpa_auth
, sm
->addr
,
2810 identity
, identity_len
) < 0 ||
2811 wpa_ft_set_radius_cui(sm
->wpa_auth
, sm
->addr
,
2812 radius_cui
, radius_cui_len
) < 0) {
2813 wpa_printf(MSG_DEBUG
, "FT: Failed to configure identity/CUI");
2814 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2816 wpa_ft_set_session_timeout(sm
->wpa_auth
, sm
->addr
, session_timeout
);
2818 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
2819 2 + FT_R1KH_ID_LEN
+ 200;
2820 *resp_ies
= os_zalloc(buflen
);
2821 if (*resp_ies
== NULL
)
2825 end
= *resp_ies
+ buflen
;
2827 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
2832 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
2837 ret
= wpa_write_ftie(conf
, parse
.r0kh_id
, parse
.r0kh_id_len
,
2838 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
2843 *resp_ies_len
= pos
- *resp_ies
;
2845 return WLAN_STATUS_SUCCESS
;
2849 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2853 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
2854 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
2855 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
2856 u16 auth_transaction
, u16 status
,
2857 const u8
*ies
, size_t ies_len
),
2862 size_t resp_ies_len
;
2866 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
2867 "WPA SM not available");
2871 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
2872 " BSSID=" MACSTR
" transaction=%d",
2873 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
2874 sm
->ft_pending_cb
= cb
;
2875 sm
->ft_pending_cb_ctx
= ctx
;
2876 sm
->ft_pending_auth_transaction
= auth_transaction
;
2877 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2878 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
2881 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
2886 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
2887 " auth_transaction=%d status=%d",
2888 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
2889 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2890 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
2891 resp_ies
, resp_ies_len
);
2896 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
2899 struct wpa_ft_ies parse
;
2900 struct rsn_mdie
*mdie
;
2901 struct rsn_ftie
*ftie
;
2902 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
2903 size_t mic_len
= 16;
2909 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2911 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
2913 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2914 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2915 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2918 if (parse
.rsn
== NULL
) {
2919 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
2920 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2923 if (parse
.rsn_pmkid
== NULL
) {
2924 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2925 return WLAN_STATUS_INVALID_PMKID
;
2928 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
2930 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
2931 "with the PMKR1Name derived from auth request");
2932 return WLAN_STATUS_INVALID_PMKID
;
2935 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2936 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2937 os_memcmp(mdie
->mobility_domain
,
2938 sm
->wpa_auth
->conf
.mobility_domain
,
2939 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2940 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2941 return WLAN_STATUS_INVALID_MDIE
;
2944 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2945 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2946 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2947 return WLAN_STATUS_INVALID_FTIE
;
2950 if (os_memcmp(ftie
->snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
2951 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
2952 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2953 ftie
->snonce
, WPA_NONCE_LEN
);
2954 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
2955 sm
->SNonce
, WPA_NONCE_LEN
);
2956 return WLAN_STATUS_INVALID_FTIE
;
2959 if (os_memcmp(ftie
->anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
2960 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
2961 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
2962 ftie
->anonce
, WPA_NONCE_LEN
);
2963 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
2964 sm
->ANonce
, WPA_NONCE_LEN
);
2965 return WLAN_STATUS_INVALID_FTIE
;
2969 if (parse
.r0kh_id
== NULL
) {
2970 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
2971 return WLAN_STATUS_INVALID_FTIE
;
2974 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
2975 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
2977 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
2978 "the current R0KH-ID");
2979 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
2980 parse
.r0kh_id
, parse
.r0kh_id_len
);
2981 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
2982 sm
->r0kh_id
, sm
->r0kh_id_len
);
2983 return WLAN_STATUS_INVALID_FTIE
;
2986 if (parse
.r1kh_id
== NULL
) {
2987 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
2988 return WLAN_STATUS_INVALID_FTIE
;
2991 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
2992 FT_R1KH_ID_LEN
) != 0) {
2993 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
2995 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
2996 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
2997 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
2998 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
2999 return WLAN_STATUS_INVALID_FTIE
;
3002 if (parse
.rsn_pmkid
== NULL
||
3003 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
3005 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
3006 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
3007 return WLAN_STATUS_INVALID_PMKID
;
3012 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
3013 if (ftie
->mic_control
[1] != count
) {
3014 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
3015 "Control: received %u expected %u",
3016 ftie
->mic_control
[1], count
);
3017 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3020 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
3022 kck_len
= sm
->PTK
.kck2_len
;
3025 kck_len
= sm
->PTK
.kck_len
;
3027 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
3028 parse
.mdie
- 2, parse
.mdie_len
+ 2,
3029 parse
.ftie
- 2, parse
.ftie_len
+ 2,
3030 parse
.rsn
- 2, parse
.rsn_len
+ 2,
3031 parse
.ric
, parse
.ric_len
,
3033 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
3034 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3037 if (os_memcmp_const(mic
, ftie
->mic
, mic_len
) != 0) {
3038 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
3039 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
3040 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
3041 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
3042 ftie
->mic
, mic_len
);
3043 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
3044 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
3045 parse
.mdie
- 2, parse
.mdie_len
+ 2);
3046 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
3047 parse
.ftie
- 2, parse
.ftie_len
+ 2);
3048 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
3049 parse
.rsn
- 2, parse
.rsn_len
+ 2);
3050 return WLAN_STATUS_INVALID_FTIE
;
3053 return WLAN_STATUS_SUCCESS
;
3057 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
3059 const u8
*sta_addr
, *target_ap
;
3063 struct ft_rrb_frame
*frame
;
3069 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3070 * FT Request action frame body[variable]
3074 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
3075 "(len=%lu)", (unsigned long) len
);
3080 sta_addr
= data
+ 2;
3081 target_ap
= data
+ 8;
3085 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
3086 " Target AP=" MACSTR
" Action=%d)",
3087 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
3089 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
3090 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
3091 "STA=" MACSTR
" STA-Address=" MACSTR
,
3092 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
3097 * Do some sanity checking on the target AP address (not own and not
3098 * broadcast. This could be extended to filter based on a list of known
3099 * APs in the MD (if such a list were configured).
3101 if ((target_ap
[0] & 0x01) ||
3102 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
3103 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
3108 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
3110 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
3111 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
3115 /* RRB - Forward action frame to the target AP */
3116 frame
= os_malloc(sizeof(*frame
) + len
);
3119 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3120 frame
->packet_type
= FT_PACKET_REQUEST
;
3121 frame
->action_length
= host_to_le16(len
);
3122 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
3123 os_memcpy(frame
+ 1, data
, len
);
3125 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
3126 sizeof(*frame
) + len
);
3133 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
3134 u16 auth_transaction
, u16 resp
,
3135 const u8
*ies
, size_t ies_len
)
3137 struct wpa_state_machine
*sm
= ctx
;
3138 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
3140 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
3141 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
3145 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
3146 const u8
*current_ap
, const u8
*sta_addr
,
3147 const u8
*body
, size_t len
)
3149 struct wpa_state_machine
*sm
;
3152 size_t resp_ies_len
;
3155 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
3157 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
3162 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
3164 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
3165 sm
->ft_pending_cb_ctx
= sm
;
3166 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
3167 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
3168 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
3171 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
3176 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
3177 resp_ies
, resp_ies_len
);
3183 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
3184 const u8
*current_ap
, const u8
*sta_addr
,
3185 u16 status
, const u8
*resp_ies
,
3186 size_t resp_ies_len
)
3188 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
3190 struct ft_rrb_frame
*frame
;
3193 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
3194 " CurrentAP=" MACSTR
" status=%d",
3195 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
3196 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
3198 /* RRB - Forward action frame response to the Current AP */
3201 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
3202 * Status_Code[2] FT Request action frame body[variable]
3204 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
3206 frame
= os_malloc(sizeof(*frame
) + rlen
);
3209 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
3210 frame
->packet_type
= FT_PACKET_RESPONSE
;
3211 frame
->action_length
= host_to_le16(rlen
);
3212 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
3213 pos
= (u8
*) (frame
+ 1);
3214 *pos
++ = WLAN_ACTION_FT
;
3215 *pos
++ = 2; /* Action: Response */
3216 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
3218 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
3220 WPA_PUT_LE16(pos
, status
);
3223 os_memcpy(pos
, resp_ies
, resp_ies_len
);
3225 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
3226 sizeof(*frame
) + rlen
);
3233 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
3234 const struct tlv_list
*tlvs
,
3235 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3236 const u8
*r1kh_id
, const u8
*s1kh_id
,
3237 const struct tlv_list
*tlv_auth
,
3238 const u8
*src_addr
, u8 type
,
3239 u8
**packet
, size_t *packet_len
)
3242 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
3243 u8 f_pairwise
[sizeof(le16
)];
3244 u8 f_expires_in
[sizeof(le16
)];
3245 u8 f_session_timeout
[sizeof(le32
)];
3247 int session_timeout
;
3248 struct os_reltime now
;
3250 struct tlv_list sess_tlv
[] = {
3251 { .type
= FT_RRB_PMK_R1
, .len
= sizeof(pmk_r1
),
3253 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
3254 .data
= pmk_r1_name
},
3255 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
3256 .data
= f_pairwise
},
3257 { .type
= FT_RRB_EXPIRES_IN
, .len
= sizeof(f_expires_in
),
3258 .data
= f_expires_in
},
3259 { .type
= FT_RRB_IDENTITY
, .len
= pmk_r0
->identity_len
,
3260 .data
= pmk_r0
->identity
},
3261 { .type
= FT_RRB_RADIUS_CUI
, .len
= pmk_r0
->radius_cui_len
,
3262 .data
= pmk_r0
->radius_cui
},
3263 { .type
= FT_RRB_SESSION_TIMEOUT
,
3264 .len
= sizeof(f_session_timeout
),
3265 .data
= f_session_timeout
},
3266 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3269 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_name
, r1kh_id
,
3270 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
3272 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
3273 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
3274 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
3276 os_get_reltime(&now
);
3277 if (pmk_r0
->expiration
> now
.sec
)
3278 expires_in
= pmk_r0
->expiration
- now
.sec
;
3279 else if (pmk_r0
->expiration
)
3283 WPA_PUT_LE16(f_expires_in
, expires_in
);
3285 if (pmk_r0
->session_timeout
> now
.sec
)
3286 session_timeout
= pmk_r0
->session_timeout
- now
.sec
;
3287 else if (pmk_r0
->session_timeout
)
3288 session_timeout
= 1;
3290 session_timeout
= 0;
3291 WPA_PUT_LE32(f_session_timeout
, session_timeout
);
3293 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
3294 pmk_r0
->vlan
, src_addr
, type
,
3295 packet
, packet_len
);
3297 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
3303 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
3305 const u8
*enc
, size_t enc_len
,
3306 const u8
*auth
, size_t auth_len
,
3309 const char *msgtype
= "pull request";
3310 u8
*plain
= NULL
, *packet
= NULL
;
3311 size_t plain_len
= 0, packet_len
= 0;
3312 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
3316 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
3317 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
3318 size_t f_pmk_r0_name_len
;
3319 const struct wpa_ft_pmk_r0_sa
*r0
;
3321 struct tlv_list resp
[2];
3322 struct tlv_list resp_auth
[5];
3323 struct ft_rrb_seq f_seq
;
3325 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
3327 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3328 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3330 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
3331 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
3335 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3336 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3338 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
3341 key_len
= sizeof(r1kh
->key
);
3342 } else if (r1kh_wildcard
) {
3343 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
3344 key
= r1kh_wildcard
->key
;
3345 key_len
= sizeof(r1kh_wildcard
->key
);
3350 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
3351 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3353 seq_ret
= FT_RRB_SEQ_DROP
;
3355 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
3356 auth
, auth_len
, msgtype
, no_defer
);
3357 if (!no_defer
&& r1kh_wildcard
&&
3358 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3359 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
3360 seq_ret
= FT_RRB_SEQ_DEFER
;
3363 if (seq_ret
== FT_RRB_SEQ_DROP
)
3366 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3367 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
3368 &plain
, &plain_len
) < 0)
3372 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
3374 wpa_auth
->conf
.rkh_pos_timeout
);
3378 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3379 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
3380 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3381 enc
, enc_len
, auth
, auth_len
,
3382 &wpa_ft_rrb_rx_pull
);
3386 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
3388 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3389 wpa_auth
->conf
.rkh_pos_timeout
);
3391 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
3392 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
3395 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3396 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3398 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3399 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3403 resp
[0].type
= FT_RRB_S1KH_ID
;
3404 resp
[0].len
= f_s1kh_id_len
;
3405 resp
[0].data
= f_s1kh_id
;
3406 resp
[1].type
= FT_RRB_LAST_EMPTY
;
3408 resp
[1].data
= NULL
;
3410 resp_auth
[0].type
= FT_RRB_NONCE
;
3411 resp_auth
[0].len
= f_nonce_len
;
3412 resp_auth
[0].data
= f_nonce
;
3413 resp_auth
[1].type
= FT_RRB_SEQ
;
3414 resp_auth
[1].len
= sizeof(f_seq
);
3415 resp_auth
[1].data
= (u8
*) &f_seq
;
3416 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3417 resp_auth
[2].len
= f_r0kh_id_len
;
3418 resp_auth
[2].data
= f_r0kh_id
;
3419 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3420 resp_auth
[3].len
= f_r1kh_id_len
;
3421 resp_auth
[3].data
= f_r1kh_id
;
3422 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3423 resp_auth
[4].len
= 0;
3424 resp_auth
[4].data
= NULL
;
3426 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0) {
3427 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
3428 ret
= wpa_ft_rrb_build(key
, key_len
, resp
, NULL
, resp_auth
,
3429 NULL
, wpa_auth
->addr
,
3430 FT_PACKET_R0KH_R1KH_RESP
,
3431 &packet
, &packet_len
);
3433 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
,
3434 f_s1kh_id
, resp_auth
, wpa_auth
->addr
,
3435 FT_PACKET_R0KH_R1KH_RESP
,
3436 &packet
, &packet_len
);
3440 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3441 FT_PACKET_R0KH_R1KH_RESP
, packet
,
3452 /* @returns 0 on success
3454 * -2 if FR_RRB_PAIRWISE is missing
3456 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
3457 const u8
*src_addr
, u8 type
,
3458 const u8
*enc
, size_t enc_len
,
3459 const u8
*auth
, size_t auth_len
,
3460 const char *msgtype
, u8
*s1kh_id_out
,
3461 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
3463 const u8
*enc
, size_t enc_len
,
3464 const u8
*auth
, size_t auth_len
,
3468 size_t plain_len
= 0;
3469 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
3473 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
3474 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
3475 const u8
*f_expires_in
;
3476 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
3477 const u8
*f_identity
, *f_radius_cui
;
3478 const u8
*f_session_timeout
;
3479 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
3480 size_t f_expires_in_len
;
3481 size_t f_identity_len
, f_radius_cui_len
;
3482 size_t f_session_timeout_len
;
3486 int session_timeout
;
3487 struct vlan_description vlan
;
3489 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
3490 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
3492 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
3493 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
3495 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
3496 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
3500 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
3504 key_len
= sizeof(r0kh
->key
);
3505 } else if (r0kh_wildcard
) {
3506 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
3507 key
= r0kh_wildcard
->key
;
3508 key_len
= sizeof(r0kh_wildcard
->key
);
3513 seq_ret
= FT_RRB_SEQ_DROP
;
3515 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
3516 auth
, auth_len
, msgtype
,
3519 if (cb
&& r0kh_wildcard
&&
3520 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3521 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
3522 seq_ret
= FT_RRB_SEQ_DEFER
;
3525 if (seq_ret
== FT_RRB_SEQ_DROP
)
3528 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
3529 src_addr
, type
, &plain
, &plain_len
) < 0)
3533 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
3534 f_r0kh_id
, f_r0kh_id_len
,
3535 wpa_auth
->conf
.rkh_pos_timeout
);
3539 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
3540 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
3541 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
3542 enc
, enc_len
, auth
, auth_len
, cb
);
3546 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
3548 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3549 wpa_auth
->conf
.rkh_pos_timeout
);
3551 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
3552 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
3555 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
3558 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
3559 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
3562 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
3563 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
3564 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
3566 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, PMK_LEN
);
3567 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, PMK_LEN
);
3569 pairwise
= WPA_GET_LE16(f_pairwise
);
3571 RRB_GET_OPTIONAL(FT_RRB_EXPIRES_IN
, expires_in
, msgtype
,
3574 expires_in
= WPA_GET_LE16(f_expires_in
);
3578 wpa_printf(MSG_DEBUG
, "FT: PMK-R1 %s - expires_in=%d", msgtype
,
3581 if (wpa_ft_rrb_get_tlv_vlan(plain
, plain_len
, &vlan
) < 0) {
3582 wpa_printf(MSG_DEBUG
, "FT: Cannot parse vlan");
3583 wpa_ft_rrb_dump(plain
, plain_len
);
3587 wpa_printf(MSG_DEBUG
, "FT: vlan %d%s",
3588 le_to_host16(vlan
.untagged
), vlan
.tagged
[0] ? "+" : "");
3590 RRB_GET_OPTIONAL(FT_RRB_IDENTITY
, identity
, msgtype
, -1);
3592 wpa_hexdump_ascii(MSG_DEBUG
, "FT: Identity", f_identity
,
3595 RRB_GET_OPTIONAL(FT_RRB_RADIUS_CUI
, radius_cui
, msgtype
, -1);
3597 wpa_hexdump_ascii(MSG_DEBUG
, "FT: CUI", f_radius_cui
,
3600 RRB_GET_OPTIONAL(FT_RRB_SESSION_TIMEOUT
, session_timeout
, msgtype
,
3602 if (f_session_timeout
)
3603 session_timeout
= WPA_GET_LE32(f_session_timeout
);
3605 session_timeout
= 0;
3606 wpa_printf(MSG_DEBUG
, "FT: session_timeout %d", session_timeout
);
3608 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, f_pmk_r1_name
,
3609 pairwise
, &vlan
, expires_in
, session_timeout
,
3610 f_identity
, f_identity_len
, f_radius_cui
,
3611 f_radius_cui_len
) < 0)
3617 os_memset(plain
, 0, plain_len
);
3626 static void ft_finish_pull(struct wpa_state_machine
*sm
)
3630 size_t resp_ies_len
;
3633 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
3636 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
3637 wpabuf_len(sm
->ft_pending_req_ies
),
3638 &resp_ies
, &resp_ies_len
);
3640 /* this loop is broken by ft_pending_pull_left_retries */
3641 wpa_printf(MSG_DEBUG
,
3642 "FT: Callback postponed until response is available");
3645 wpabuf_free(sm
->ft_pending_req_ies
);
3646 sm
->ft_pending_req_ies
= NULL
;
3648 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
3649 " - status %u", MAC2STR(sm
->addr
), status
);
3651 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
3652 sm
->ft_pending_auth_transaction
+ 1, status
,
3653 resp_ies
, resp_ies_len
);
3658 struct ft_get_sta_ctx
{
3661 struct wpa_state_machine
*sm
;
3665 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3667 struct ft_get_sta_ctx
*info
= ctx
;
3669 if ((info
->s1kh_id
&&
3670 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3671 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3672 FT_RRB_NONCE_LEN
) != 0 ||
3673 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3682 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3684 const u8
*enc
, size_t enc_len
,
3685 const u8
*auth
, size_t auth_len
,
3688 const char *msgtype
= "pull response";
3690 struct ft_get_sta_ctx ctx
;
3691 u8 s1kh_id
[ETH_ALEN
];
3695 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3697 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3698 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3700 os_memset(&ctx
, 0, sizeof(ctx
));
3701 ctx
.nonce
= f_nonce
;
3702 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3703 /* nonce not found */
3704 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3708 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3709 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3710 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3720 ctx
.s1kh_id
= s1kh_id
;
3721 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3722 wpa_printf(MSG_DEBUG
,
3723 "FT: Response to a pending pull request for " MACSTR
,
3724 MAC2STR(ctx
.sm
->addr
));
3725 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3727 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3728 ft_finish_pull(ctx
.sm
);
3736 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
3738 const u8
*enc
, size_t enc_len
,
3739 const u8
*auth
, size_t auth_len
, int no_defer
)
3741 const char *msgtype
= "push";
3743 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
3745 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3746 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
3747 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
3754 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
3755 const u8
*src_addr
, int type
,
3756 const u8
*enc
, size_t enc_len
,
3757 const u8
*auth
, size_t auth_len
,
3758 struct ft_remote_seq
**rkh_seq
,
3759 u8
**key
, size_t *key_len
,
3760 struct ft_remote_r0kh
**r0kh_out
,
3761 struct ft_remote_r1kh
**r1kh_out
,
3762 struct ft_remote_r0kh
**r0kh_wildcard_out
,
3763 struct ft_remote_r1kh
**r1kh_wildcard_out
)
3765 struct ft_remote_r0kh
*r0kh
= NULL
;
3766 struct ft_remote_r1kh
*r1kh
= NULL
;
3767 const u8
*f_r0kh_id
, *f_r1kh_id
;
3768 size_t f_r0kh_id_len
, f_r1kh_id_len
;
3769 int to_r0kh
, to_r1kh
;
3771 size_t plain_len
= 0;
3772 struct ft_remote_r0kh
*r0kh_wildcard
;
3773 struct ft_remote_r1kh
*r1kh_wildcard
;
3775 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3776 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3778 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
3779 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
3781 if (to_r0kh
&& to_r1kh
) {
3782 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
3786 if (!to_r0kh
&& !to_r1kh
) {
3787 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
3792 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
3793 &r0kh
, &r0kh_wildcard
);
3794 if (!r0kh_wildcard
&&
3795 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3796 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
3797 f_r0kh_id
, f_r0kh_id_len
);
3802 *key_len
= sizeof(r0kh
->key
);
3804 *key
= r0kh_wildcard
->key
;
3805 *key_len
= sizeof(r0kh_wildcard
->key
);
3810 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
3812 if (!r1kh_wildcard
&&
3813 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3814 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
3815 f_r1kh_id
, FT_R1KH_ID_LEN
);
3820 *key_len
= sizeof(r1kh
->key
);
3822 *key
= r1kh_wildcard
->key
;
3823 *key_len
= sizeof(r1kh_wildcard
->key
);
3827 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
3828 src_addr
, type
, &plain
, &plain_len
) < 0)
3835 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
3836 src_addr
, f_r0kh_id
,
3842 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
3843 *rkh_seq
= r0kh
->seq
;
3846 if (r0kh_wildcard_out
)
3847 *r0kh_wildcard_out
= r0kh_wildcard
;
3852 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
3853 src_addr
, f_r1kh_id
,
3858 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
3859 *rkh_seq
= r1kh
->seq
;
3862 if (r1kh_wildcard_out
)
3863 *r1kh_wildcard_out
= r1kh_wildcard
;
3872 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
3874 const u8
*enc
, size_t enc_len
,
3875 const u8
*auth
, size_t auth_len
,
3879 struct ft_rrb_seq f_seq
;
3880 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
3881 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
3882 struct ft_remote_seq
*rkh_seq
= NULL
;
3883 u8
*packet
= NULL
, *key
= NULL
;
3884 size_t packet_len
= 0, key_len
= 0;
3885 struct tlv_list seq_resp_auth
[5];
3887 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
3889 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
3890 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3891 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
3894 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
3895 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
3897 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3898 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3900 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
3901 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3905 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
3906 seq_resp_auth
[0].len
= f_nonce_len
;
3907 seq_resp_auth
[0].data
= f_nonce
;
3908 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
3909 seq_resp_auth
[1].len
= sizeof(f_seq
);
3910 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
3911 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3912 seq_resp_auth
[2].len
= f_r0kh_id_len
;
3913 seq_resp_auth
[2].data
= f_r0kh_id
;
3914 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3915 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
3916 seq_resp_auth
[3].data
= f_r1kh_id
;
3917 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3918 seq_resp_auth
[4].len
= 0;
3919 seq_resp_auth
[4].data
= NULL
;
3921 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
, NULL
,
3922 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3923 &packet
, &packet_len
) < 0)
3926 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3927 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
3937 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
3939 const u8
*enc
, size_t enc_len
,
3940 const u8
*auth
, size_t auth_len
,
3945 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
3946 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
3947 const u8
*f_nonce
, *f_seq
;
3948 size_t f_nonce_len
, f_seq_len
;
3949 struct ft_remote_seq
*rkh_seq
= NULL
;
3950 struct ft_remote_item
*item
;
3951 struct os_reltime now
, now_remote
;
3953 const struct ft_rrb_seq
*msg_both
;
3954 u32 msg_dom
, msg_seq
;
3956 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
3958 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3959 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3960 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
3961 &r1kh_wildcard
) < 0)
3964 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
3965 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
3969 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
3971 if (os_memcmp_const(f_nonce
, item
->nonce
,
3972 FT_RRB_NONCE_LEN
) != 0 ||
3973 os_get_reltime(&now
) < 0 ||
3974 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
3981 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
3986 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3987 wpa_auth
->conf
.rkh_pos_timeout
);
3989 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
3993 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3994 wpa_auth
->conf
.rkh_pos_timeout
);
3996 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
3999 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
4000 auth_len
, "seq response", 1);
4001 if (seq_ret
== FT_RRB_SEQ_OK
) {
4002 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
4003 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
4004 auth_len
, "seq response");
4006 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
4008 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
4010 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
4012 msg_dom
= le_to_host32(msg_both
->dom
);
4013 msg_seq
= le_to_host32(msg_both
->seq
);
4014 now_remote
.sec
= le_to_host32(msg_both
->ts
);
4015 now_remote
.usec
= 0;
4017 rkh_seq
->rx
.num_last
= 2;
4018 rkh_seq
->rx
.dom
= msg_dom
;
4019 rkh_seq
->rx
.offsetidx
= 0;
4020 /* Accept some older, possibly cached packets as well */
4021 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
4022 dl_list_len(&rkh_seq
->rx
.queue
);
4023 rkh_seq
->rx
.last
[1] = msg_seq
;
4025 /* local time - offset = remote time
4026 * <=> local time - remote time = offset */
4027 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
4030 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
4038 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4039 const u8
*data
, size_t data_len
)
4041 struct ft_rrb_frame
*frame
;
4043 const u8
*pos
, *end
, *start
;
4045 const u8
*sta_addr
, *target_ap_addr
;
4047 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
4050 if (data_len
< sizeof(*frame
)) {
4051 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
4052 (unsigned long) data_len
);
4057 frame
= (struct ft_rrb_frame
*) pos
;
4058 pos
+= sizeof(*frame
);
4060 alen
= le_to_host16(frame
->action_length
);
4061 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
4062 "action_length=%d ap_address=" MACSTR
,
4063 frame
->frame_type
, frame
->packet_type
, alen
,
4064 MAC2STR(frame
->ap_address
));
4066 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
4067 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
4068 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
4069 "unrecognized type %d", frame
->frame_type
);
4073 if (alen
> data_len
- sizeof(*frame
)) {
4074 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
4079 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
4081 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
4082 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
4083 "room for Action Frame body); alen=%lu",
4084 (unsigned long) alen
);
4090 if (*pos
!= WLAN_ACTION_FT
) {
4091 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
4100 target_ap_addr
= pos
;
4102 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
4103 MACSTR
" target_ap_addr=" MACSTR
,
4104 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
4106 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
4107 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
4110 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
4111 "RRB Request", action
);
4115 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
4116 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
4117 "RRB Request does not match with own "
4122 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
4123 sta_addr
, pos
, end
- pos
) < 0)
4125 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
4128 if (end
- pos
< 2) {
4129 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
4130 "code in RRB Response");
4133 status_code
= WPA_GET_LE16(pos
);
4136 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
4137 "(status_code=%d)", status_code
);
4139 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
4142 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
4143 "packet_type %d", frame
->packet_type
);
4148 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
4156 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
4157 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
4160 const u8
*auth
, *enc
;
4164 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
4165 MACSTR
, MAC2STR(src_addr
));
4166 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
4168 if (is_multicast_ether_addr(src_addr
)) {
4169 wpa_printf(MSG_DEBUG
,
4170 "FT: RRB-OUI received frame from multicast address "
4171 MACSTR
, MAC2STR(src_addr
));
4175 if (is_multicast_ether_addr(dst_addr
)) {
4176 wpa_printf(MSG_DEBUG
,
4177 "FT: RRB-OUI received frame from remote AP " MACSTR
4178 " to multicast address " MACSTR
,
4179 MAC2STR(src_addr
), MAC2STR(dst_addr
));
4183 if (data_len
< sizeof(u16
)) {
4184 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4188 alen
= WPA_GET_LE16(data
);
4189 if (data_len
< sizeof(u16
) + alen
) {
4190 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
4194 auth
= data
+ sizeof(u16
);
4195 enc
= data
+ sizeof(u16
) + alen
;
4196 elen
= data_len
- sizeof(u16
) - alen
;
4198 switch (oui_suffix
) {
4199 case FT_PACKET_R0KH_R1KH_PULL
:
4200 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4203 case FT_PACKET_R0KH_R1KH_RESP
:
4204 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4207 case FT_PACKET_R0KH_R1KH_PUSH
:
4208 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4211 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
4212 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
4215 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
4216 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
4223 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
4224 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
4225 struct ft_remote_r1kh
*r1kh
,
4230 struct ft_rrb_seq f_seq
;
4231 struct tlv_list push
[] = {
4232 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
4234 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
4235 .data
= pmk_r0
->pmk_r0_name
},
4236 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4238 struct tlv_list push_auth
[] = {
4239 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
4240 .data
= (u8
*) &f_seq
},
4241 { .type
= FT_RRB_R0KH_ID
,
4242 .len
= wpa_auth
->conf
.r0_key_holder_len
,
4243 .data
= wpa_auth
->conf
.r0_key_holder
},
4244 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
4246 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
4249 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
4250 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
4254 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
4255 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
4256 FT_PACKET_R0KH_R1KH_PUSH
,
4257 &packet
, &packet_len
) < 0)
4260 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
4261 packet
, packet_len
);
4268 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
4270 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
4271 struct wpa_ft_pmk_r0_sa
*r0
, *r0found
= NULL
;
4272 struct ft_remote_r1kh
*r1kh
;
4274 if (!wpa_auth
->conf
.pmk_r1_push
)
4276 if (!wpa_auth
->conf
.r1kh_list
)
4279 dl_list_for_each(r0
, &cache
->pmk_r0
, struct wpa_ft_pmk_r0_sa
, list
) {
4280 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0) {
4287 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
4289 r0
->pmk_r1_pushed
= 1;
4291 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
4292 "for STA " MACSTR
, MAC2STR(addr
));
4294 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
4295 if (is_zero_ether_addr(r1kh
->addr
) ||
4296 is_zero_ether_addr(r1kh
->id
))
4298 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
4300 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
4304 #endif /* CONFIG_IEEE80211R_AP */