2 * hostapd - IEEE 802.11r - Fast BSS Transition
3 * Copyright (c) 2004-2015, 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 size_t wpa_ft_tlv_len(const struct tlv_list
*tlvs
)
203 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
204 tlv_len
+= sizeof(struct ft_rrb_tlv
);
205 tlv_len
+= tlvs
[i
].len
;
212 static size_t wpa_ft_tlv_lin(const struct tlv_list
*tlvs
, u8
*start
,
217 struct ft_rrb_tlv
*hdr
;
225 for (i
= 0; tlvs
[i
].type
!= FT_RRB_LAST_EMPTY
; i
++) {
226 if (tlv_len
+ sizeof(*hdr
) > (size_t) (endpos
- start
))
228 tlv_len
+= sizeof(*hdr
);
229 hdr
= (struct ft_rrb_tlv
*) pos
;
230 hdr
->type
= host_to_le16(tlvs
[i
].type
);
231 hdr
->len
= host_to_le16(tlvs
[i
].len
);
232 pos
= start
+ tlv_len
;
234 if (tlv_len
+ tlvs
[i
].len
> (size_t) (endpos
- start
))
236 tlv_len
+= tlvs
[i
].len
;
237 os_memcpy(pos
, tlvs
[i
].data
, tlvs
[i
].len
);
238 pos
= start
+ tlv_len
;
245 static int wpa_ft_rrb_lin(const struct tlv_list
*tlvs1
,
246 const struct tlv_list
*tlvs2
,
247 u8
**plain
, size_t *plain_len
)
252 tlv_len
= wpa_ft_tlv_len(tlvs1
);
253 tlv_len
+= wpa_ft_tlv_len(tlvs2
);
255 *plain_len
= tlv_len
;
256 *plain
= os_zalloc(tlv_len
);
258 wpa_printf(MSG_ERROR
, "FT: Failed to allocate plaintext");
263 endpos
= *plain
+ tlv_len
;
264 pos
+= wpa_ft_tlv_lin(tlvs1
, pos
, endpos
);
265 pos
+= wpa_ft_tlv_lin(tlvs2
, pos
, endpos
);
269 wpa_printf(MSG_ERROR
, "FT: Length error building RRB");
283 static int wpa_ft_rrb_encrypt(const u8
*key
, const size_t key_len
,
284 const u8
*plain
, const size_t plain_len
,
285 const u8
*auth
, const size_t auth_len
,
286 const u8
*src_addr
, u8 type
, u8
*enc
)
288 const u8
*ad
[3] = { src_addr
, auth
, &type
};
289 size_t ad_len
[3] = { ETH_ALEN
, auth_len
, sizeof(type
) };
291 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): plaintext message",
293 wpa_hexdump_key(MSG_DEBUG
, "FT(RRB): encrypt using key", key
, key_len
);
296 /* encryption not needed, return plaintext as packet */
297 os_memcpy(enc
, plain
, plain_len
);
298 } else if (aes_siv_encrypt(key
, key_len
, plain
, plain_len
,
299 3, ad
, ad_len
, enc
) < 0) {
300 wpa_printf(MSG_ERROR
, "FT: Failed to encrypt RRB-OUI message");
309 * wpa_ft_rrb_build - Build and encrypt an FT RRB message
310 * @key: AES-SIV key for AEAD
311 * @key_len: Length of key in octets
312 * @tlvs_enc0: First set of to-be-encrypted TLVs
313 * @tlvs_enc1: Second set of to-be-encrypted TLVs
314 * @tlvs_auth: Set of to-be-authenticated TLVs
315 * @src_addr: MAC address of the frame sender
316 * @type: Vendor-specific subtype of the RRB frame (FT_PACKET_*)
317 * @packet Pointer to return the pointer to the allocated packet buffer;
318 * needs to be freed by the caller if not null;
319 * will only be returned on success
320 * @packet_len: Pointer to return the length of the allocated buffer in octets
321 * Returns: 0 on success, -1 on error
323 static int wpa_ft_rrb_build(const u8
*key
, const size_t key_len
,
324 const struct tlv_list
*tlvs_enc0
,
325 const struct tlv_list
*tlvs_enc1
,
326 const struct tlv_list
*tlvs_auth
,
327 const u8
*src_addr
, u8 type
,
328 u8
**packet
, size_t *packet_len
)
330 u8
*plain
= NULL
, *auth
= NULL
, *pos
;
331 size_t plain_len
= 0, auth_len
= 0;
334 if (wpa_ft_rrb_lin(tlvs_enc0
, tlvs_enc1
, &plain
, &plain_len
) < 0)
337 if (wpa_ft_rrb_lin(tlvs_auth
, NULL
, &auth
, &auth_len
) < 0)
340 *packet_len
= sizeof(u16
) + auth_len
+ plain_len
;
342 *packet_len
+= AES_BLOCK_SIZE
;
343 *packet
= os_zalloc(*packet_len
);
348 WPA_PUT_LE16(pos
, auth_len
);
350 os_memcpy(pos
, auth
, auth_len
);
352 if (wpa_ft_rrb_encrypt(key
, key_len
, plain
, plain_len
, auth
,
353 auth_len
, src_addr
, type
, pos
) < 0)
359 bin_clear_free(plain
, plain_len
);
363 wpa_printf(MSG_ERROR
, "FT: Failed to build RRB-OUI message");
373 #define RRB_GET_SRC(srcfield, type, field, txt, checklength) do { \
374 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
375 &f_##field##_len, &f_##field) < 0 || \
376 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
377 wpa_printf(MSG_INFO, "FT: Missing required " #field \
378 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
379 wpa_ft_rrb_dump(srcfield, srcfield##_len); \
384 #define RRB_GET(type, field, txt, checklength) \
385 RRB_GET_SRC(plain, type, field, txt, checklength)
386 #define RRB_GET_AUTH(type, field, txt, checklength) \
387 RRB_GET_SRC(auth, type, field, txt, checklength)
389 #define RRB_GET_OPTIONAL_SRC(srcfield, type, field, txt, checklength) do { \
390 if (wpa_ft_rrb_get_tlv(srcfield, srcfield##_len, type, \
391 &f_##field##_len, &f_##field) < 0 || \
392 (checklength > 0 && ((size_t) checklength) != f_##field##_len)) { \
393 wpa_printf(MSG_DEBUG, "FT: Missing optional " #field \
394 " in %s from " MACSTR, txt, MAC2STR(src_addr)); \
395 f_##field##_len = 0; \
400 #define RRB_GET_OPTIONAL(type, field, txt, checklength) \
401 RRB_GET_OPTIONAL_SRC(plain, type, field, txt, checklength)
402 #define RRB_GET_OPTIONAL_AUTH(type, field, txt, checklength) \
403 RRB_GET_OPTIONAL_SRC(auth, type, field, txt, checklength)
405 static int wpa_ft_rrb_send(struct wpa_authenticator
*wpa_auth
, const u8
*dst
,
406 const u8
*data
, size_t data_len
)
408 if (wpa_auth
->cb
->send_ether
== NULL
)
410 wpa_printf(MSG_DEBUG
, "FT: RRB send to " MACSTR
, MAC2STR(dst
));
411 return wpa_auth
->cb
->send_ether(wpa_auth
->cb_ctx
, dst
, ETH_P_RRB
,
416 static int wpa_ft_rrb_oui_send(struct wpa_authenticator
*wpa_auth
,
417 const u8
*dst
, u8 oui_suffix
,
418 const u8
*data
, size_t data_len
)
420 if (!wpa_auth
->cb
->send_oui
)
422 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI type %u send to " MACSTR
,
423 oui_suffix
, MAC2STR(dst
));
424 return wpa_auth
->cb
->send_oui(wpa_auth
->cb_ctx
, dst
, oui_suffix
, data
,
429 static int wpa_ft_action_send(struct wpa_authenticator
*wpa_auth
,
430 const u8
*dst
, const u8
*data
, size_t data_len
)
432 if (wpa_auth
->cb
->send_ft_action
== NULL
)
434 return wpa_auth
->cb
->send_ft_action(wpa_auth
->cb_ctx
, dst
,
439 static const u8
* wpa_ft_get_psk(struct wpa_authenticator
*wpa_auth
,
440 const u8
*addr
, const u8
*p2p_dev_addr
,
443 if (wpa_auth
->cb
->get_psk
== NULL
)
445 return wpa_auth
->cb
->get_psk(wpa_auth
->cb_ctx
, addr
, p2p_dev_addr
,
450 static struct wpa_state_machine
*
451 wpa_ft_add_sta(struct wpa_authenticator
*wpa_auth
, const u8
*sta_addr
)
453 if (wpa_auth
->cb
->add_sta
== NULL
)
455 return wpa_auth
->cb
->add_sta(wpa_auth
->cb_ctx
, sta_addr
);
459 static int wpa_ft_add_tspec(struct wpa_authenticator
*wpa_auth
,
461 u8
*tspec_ie
, size_t tspec_ielen
)
463 if (wpa_auth
->cb
->add_tspec
== NULL
) {
464 wpa_printf(MSG_DEBUG
, "FT: add_tspec is not initialized");
467 return wpa_auth
->cb
->add_tspec(wpa_auth
->cb_ctx
, sta_addr
, tspec_ie
,
472 int wpa_write_mdie(struct wpa_auth_config
*conf
, u8
*buf
, size_t len
)
476 if (len
< 2 + sizeof(struct rsn_mdie
))
479 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
480 *pos
++ = MOBILITY_DOMAIN_ID_LEN
+ 1;
481 os_memcpy(pos
, conf
->mobility_domain
, MOBILITY_DOMAIN_ID_LEN
);
482 pos
+= MOBILITY_DOMAIN_ID_LEN
;
484 if (conf
->ft_over_ds
)
485 capab
|= RSN_FT_CAPAB_FT_OVER_DS
;
492 int wpa_write_ftie(struct wpa_auth_config
*conf
, const u8
*r0kh_id
,
494 const u8
*anonce
, const u8
*snonce
,
495 u8
*buf
, size_t len
, const u8
*subelem
,
498 u8
*pos
= buf
, *ielen
;
499 struct rsn_ftie
*hdr
;
501 if (len
< 2 + sizeof(*hdr
) + 2 + FT_R1KH_ID_LEN
+ 2 + r0kh_id_len
+
505 *pos
++ = WLAN_EID_FAST_BSS_TRANSITION
;
508 hdr
= (struct rsn_ftie
*) pos
;
509 os_memset(hdr
, 0, sizeof(*hdr
));
511 WPA_PUT_LE16(hdr
->mic_control
, 0);
513 os_memcpy(hdr
->anonce
, anonce
, WPA_NONCE_LEN
);
515 os_memcpy(hdr
->snonce
, snonce
, WPA_NONCE_LEN
);
517 /* Optional Parameters */
518 *pos
++ = FTIE_SUBELEM_R1KH_ID
;
519 *pos
++ = FT_R1KH_ID_LEN
;
520 os_memcpy(pos
, conf
->r1_key_holder
, FT_R1KH_ID_LEN
);
521 pos
+= FT_R1KH_ID_LEN
;
524 *pos
++ = FTIE_SUBELEM_R0KH_ID
;
525 *pos
++ = r0kh_id_len
;
526 os_memcpy(pos
, r0kh_id
, r0kh_id_len
);
531 os_memcpy(pos
, subelem
, subelem_len
);
535 *ielen
= pos
- buf
- 2;
541 /* A packet to be handled after seq response */
542 struct ft_remote_item
{
545 u8 nonce
[FT_RRB_NONCE_LEN
];
546 struct os_reltime nonce_ts
;
548 u8 src_addr
[ETH_ALEN
];
553 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
555 const u8
*enc
, size_t enc_len
,
556 const u8
*auth
, size_t auth_len
,
561 static void wpa_ft_rrb_seq_free(struct ft_remote_item
*item
)
563 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, ELOOP_ALL_CTX
, item
);
564 dl_list_del(&item
->list
);
565 bin_clear_free(item
->enc
, item
->enc_len
);
571 static void wpa_ft_rrb_seq_flush(struct wpa_authenticator
*wpa_auth
,
572 struct ft_remote_seq
*rkh_seq
, int cb
)
574 struct ft_remote_item
*item
, *n
;
576 dl_list_for_each_safe(item
, n
, &rkh_seq
->rx
.queue
,
577 struct ft_remote_item
, list
) {
579 item
->cb(wpa_auth
, item
->src_addr
, item
->enc
,
580 item
->enc_len
, item
->auth
, item
->auth_len
, 1);
581 wpa_ft_rrb_seq_free(item
);
586 static void wpa_ft_rrb_seq_timeout(void *eloop_ctx
, void *timeout_ctx
)
588 struct ft_remote_item
*item
= timeout_ctx
;
590 wpa_ft_rrb_seq_free(item
);
595 wpa_ft_rrb_seq_req(struct wpa_authenticator
*wpa_auth
,
596 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
597 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
598 const u8
*f_r1kh_id
, const u8
*key
, size_t key_len
,
599 const u8
*enc
, size_t enc_len
,
600 const u8
*auth
, size_t auth_len
,
601 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
603 const u8
*enc
, size_t enc_len
,
604 const u8
*auth
, size_t auth_len
,
607 struct ft_remote_item
*item
= NULL
;
610 struct tlv_list seq_req_auth
[] = {
611 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
612 .data
= NULL
/* to be filled: item->nonce */ },
613 { .type
= FT_RRB_R0KH_ID
, .len
= f_r0kh_id_len
,
615 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
617 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
620 if (dl_list_len(&rkh_seq
->rx
.queue
) >= ftRRBmaxQueueLen
) {
621 wpa_printf(MSG_DEBUG
, "FT: Sequence number queue too long");
625 item
= os_zalloc(sizeof(*item
));
629 os_memcpy(item
->src_addr
, src_addr
, ETH_ALEN
);
632 if (random_get_bytes(item
->nonce
, FT_RRB_NONCE_LEN
) < 0) {
633 wpa_printf(MSG_DEBUG
, "FT: Seq num nonce: out of random bytes");
637 if (os_get_reltime(&item
->nonce_ts
) < 0)
640 if (enc
&& enc_len
> 0) {
641 item
->enc
= os_memdup(enc
, enc_len
);
642 item
->enc_len
= enc_len
;
647 if (auth
&& auth_len
> 0) {
648 item
->auth
= os_memdup(auth
, auth_len
);
649 item
->auth_len
= auth_len
;
654 eloop_register_timeout(ftRRBseqTimeout
, 0, wpa_ft_rrb_seq_timeout
,
657 seq_req_auth
[0].data
= item
->nonce
;
659 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_req_auth
,
660 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
661 &packet
, &packet_len
) < 0) {
662 item
= NULL
; /* some other seq resp might still accept this */
666 dl_list_add(&rkh_seq
->rx
.queue
, &item
->list
);
668 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
675 wpa_printf(MSG_DEBUG
, "FT: Failed to send sequence number request");
678 bin_clear_free(item
->enc
, item
->enc_len
);
686 #define FT_RRB_SEQ_OK 0
687 #define FT_RRB_SEQ_DROP 1
688 #define FT_RRB_SEQ_DEFER 2
691 wpa_ft_rrb_seq_chk(struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
692 const u8
*enc
, size_t enc_len
,
693 const u8
*auth
, size_t auth_len
,
694 const char *msgtype
, int no_defer
)
698 const struct ft_rrb_seq
*msg_both
;
699 u32 msg_seq
, msg_off
, rkh_off
;
700 struct os_reltime now
;
703 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
704 wpa_hexdump(MSG_DEBUG
, "FT: sequence number", f_seq
, f_seq_len
);
705 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
707 if (rkh_seq
->rx
.num_last
== 0) {
708 /* first packet from remote */
712 if (le_to_host32(msg_both
->dom
) != rkh_seq
->rx
.dom
) {
713 /* remote might have rebooted */
717 if (os_get_reltime(&now
) == 0) {
718 u32 msg_ts_now_remote
, msg_ts_off
;
719 struct os_reltime now_remote
;
721 os_reltime_sub(&now
, &rkh_seq
->rx
.time_offset
, &now_remote
);
722 msg_ts_now_remote
= now_remote
.sec
;
723 msg_ts_off
= le_to_host32(msg_both
->ts
) -
724 (msg_ts_now_remote
- ftRRBseqTimeout
);
725 if (msg_ts_off
> 2 * ftRRBseqTimeout
)
729 msg_seq
= le_to_host32(msg_both
->seq
);
730 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
731 msg_off
= msg_seq
- rkh_off
;
732 if (msg_off
> 0xC0000000)
733 goto out
; /* too old message, drop it */
735 if (msg_off
<= 0x40000000) {
736 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
737 if (rkh_seq
->rx
.last
[i
] == msg_seq
)
738 goto out
; /* duplicate message, drop it */
741 return FT_RRB_SEQ_OK
;
748 wpa_printf(MSG_DEBUG
, "FT: Possibly invalid sequence number in %s from "
749 MACSTR
, msgtype
, MAC2STR(src_addr
));
751 return FT_RRB_SEQ_DEFER
;
753 wpa_printf(MSG_DEBUG
, "FT: Invalid sequence number in %s from " MACSTR
,
754 msgtype
, MAC2STR(src_addr
));
756 return FT_RRB_SEQ_DROP
;
761 wpa_ft_rrb_seq_accept(struct wpa_authenticator
*wpa_auth
,
762 struct ft_remote_seq
*rkh_seq
, const u8
*src_addr
,
763 const u8
*auth
, size_t auth_len
,
768 const struct ft_rrb_seq
*msg_both
;
769 u32 msg_seq
, msg_off
, min_off
, rkh_off
;
773 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, msgtype
, sizeof(*msg_both
));
774 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
776 msg_seq
= le_to_host32(msg_both
->seq
);
778 if (rkh_seq
->rx
.num_last
< FT_REMOTE_SEQ_BACKLOG
) {
779 rkh_seq
->rx
.last
[rkh_seq
->rx
.num_last
] = msg_seq
;
780 rkh_seq
->rx
.num_last
++;
784 rkh_off
= rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
];
785 for (i
= 0; i
< rkh_seq
->rx
.num_last
; i
++) {
786 msg_off
= rkh_seq
->rx
.last
[i
] - rkh_off
;
787 min_off
= rkh_seq
->rx
.last
[minidx
] - rkh_off
;
788 if (msg_off
< min_off
&& i
!= rkh_seq
->rx
.offsetidx
)
791 rkh_seq
->rx
.last
[rkh_seq
->rx
.offsetidx
] = msg_seq
;
792 rkh_seq
->rx
.offsetidx
= minidx
;
796 /* RRB_GET_AUTH should never fail here as
797 * wpa_ft_rrb_seq_chk() verified FT_RRB_SEQ presence. */
798 wpa_printf(MSG_ERROR
, "FT: %s() failed", __func__
);
802 static int wpa_ft_new_seq(struct ft_remote_seq
*rkh_seq
,
803 struct ft_rrb_seq
*f_seq
)
805 struct os_reltime now
;
807 if (os_get_reltime(&now
) < 0)
810 if (!rkh_seq
->tx
.dom
) {
811 if (random_get_bytes((u8
*) &rkh_seq
->tx
.seq
,
812 sizeof(rkh_seq
->tx
.seq
))) {
813 wpa_printf(MSG_ERROR
,
814 "FT: Failed to get random data for sequence number initialization");
815 rkh_seq
->tx
.seq
= now
.usec
;
817 if (random_get_bytes((u8
*) &rkh_seq
->tx
.dom
,
818 sizeof(rkh_seq
->tx
.dom
))) {
819 wpa_printf(MSG_ERROR
,
820 "FT: Failed to get random data for sequence number initialization");
821 rkh_seq
->tx
.dom
= now
.usec
;
823 rkh_seq
->tx
.dom
|= 1;
826 f_seq
->dom
= host_to_le32(rkh_seq
->tx
.dom
);
827 f_seq
->seq
= host_to_le32(rkh_seq
->tx
.seq
);
828 f_seq
->ts
= host_to_le32(now
.sec
);
836 struct wpa_ft_pmk_r0_sa
{
837 struct wpa_ft_pmk_r0_sa
*next
;
839 u8 pmk_r0_name
[WPA_PMK_NAME_LEN
];
841 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
842 /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
846 struct wpa_ft_pmk_r1_sa
{
847 struct wpa_ft_pmk_r1_sa
*next
;
849 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
851 int pairwise
; /* Pairwise cipher suite, WPA_CIPHER_* */
852 /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
855 struct wpa_ft_pmk_cache
{
856 struct wpa_ft_pmk_r0_sa
*pmk_r0
;
857 struct wpa_ft_pmk_r1_sa
*pmk_r1
;
860 struct wpa_ft_pmk_cache
* wpa_ft_pmk_cache_init(void)
862 struct wpa_ft_pmk_cache
*cache
;
864 cache
= os_zalloc(sizeof(*cache
));
870 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache
*cache
)
872 struct wpa_ft_pmk_r0_sa
*r0
, *r0prev
;
873 struct wpa_ft_pmk_r1_sa
*r1
, *r1prev
;
879 os_memset(r0prev
->pmk_r0
, 0, PMK_LEN
);
887 os_memset(r1prev
->pmk_r1
, 0, PMK_LEN
);
895 int wpa_ft_store_pmk_r0(struct wpa_authenticator
*wpa_auth
,
896 const u8
*spa
, const u8
*pmk_r0
,
897 const u8
*pmk_r0_name
, int pairwise
)
899 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
900 struct wpa_ft_pmk_r0_sa
*r0
;
902 /* TODO: add expiration and limit on number of entries in cache */
904 r0
= os_zalloc(sizeof(*r0
));
908 os_memcpy(r0
->pmk_r0
, pmk_r0
, PMK_LEN
);
909 os_memcpy(r0
->pmk_r0_name
, pmk_r0_name
, WPA_PMK_NAME_LEN
);
910 os_memcpy(r0
->spa
, spa
, ETH_ALEN
);
911 r0
->pairwise
= pairwise
;
913 r0
->next
= cache
->pmk_r0
;
920 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator
*wpa_auth
,
921 const u8
*spa
, const u8
*pmk_r0_name
,
922 const struct wpa_ft_pmk_r0_sa
**r0_out
)
924 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
925 struct wpa_ft_pmk_r0_sa
*r0
;
929 if (os_memcmp(r0
->spa
, spa
, ETH_ALEN
) == 0 &&
930 os_memcmp_const(r0
->pmk_r0_name
, pmk_r0_name
,
931 WPA_PMK_NAME_LEN
) == 0) {
944 static int wpa_ft_store_pmk_r1(struct wpa_authenticator
*wpa_auth
,
945 const u8
*spa
, const u8
*pmk_r1
,
946 const u8
*pmk_r1_name
, int pairwise
)
948 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
949 struct wpa_ft_pmk_r1_sa
*r1
;
951 /* TODO: add expiration and limit on number of entries in cache */
953 r1
= os_zalloc(sizeof(*r1
));
957 os_memcpy(r1
->pmk_r1
, pmk_r1
, PMK_LEN
);
958 os_memcpy(r1
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
959 os_memcpy(r1
->spa
, spa
, ETH_ALEN
);
960 r1
->pairwise
= pairwise
;
962 r1
->next
= cache
->pmk_r1
;
969 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator
*wpa_auth
,
970 const u8
*spa
, const u8
*pmk_r1_name
,
971 u8
*pmk_r1
, int *pairwise
)
973 struct wpa_ft_pmk_cache
*cache
= wpa_auth
->ft_pmk_cache
;
974 struct wpa_ft_pmk_r1_sa
*r1
;
978 if (os_memcmp(r1
->spa
, spa
, ETH_ALEN
) == 0 &&
979 os_memcmp_const(r1
->pmk_r1_name
, pmk_r1_name
,
980 WPA_PMK_NAME_LEN
) == 0) {
981 os_memcpy(pmk_r1
, r1
->pmk_r1
, PMK_LEN
);
983 *pairwise
= r1
->pairwise
;
994 static int wpa_ft_rrb_init_r0kh_seq(struct ft_remote_r0kh
*r0kh
)
999 r0kh
->seq
= os_zalloc(sizeof(*r0kh
->seq
));
1001 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r0kh->seq");
1005 dl_list_init(&r0kh
->seq
->rx
.queue
);
1011 static void wpa_ft_rrb_lookup_r0kh(struct wpa_authenticator
*wpa_auth
,
1012 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
,
1013 struct ft_remote_r0kh
**r0kh_out
,
1014 struct ft_remote_r0kh
**r0kh_wildcard
)
1016 struct ft_remote_r0kh
*r0kh
;
1018 *r0kh_wildcard
= NULL
;
1021 if (wpa_auth
->conf
.r0kh_list
)
1022 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1025 for (; r0kh
; r0kh
= r0kh
->next
) {
1026 if (r0kh
->id_len
== 1 && r0kh
->id
[0] == '*')
1027 *r0kh_wildcard
= r0kh
;
1028 if (f_r0kh_id
&& r0kh
->id_len
== f_r0kh_id_len
&&
1029 os_memcmp_const(f_r0kh_id
, r0kh
->id
, f_r0kh_id_len
) == 0)
1033 if (!*r0kh_out
&& !*r0kh_wildcard
)
1034 wpa_printf(MSG_DEBUG
, "FT: No matching R0KH found");
1036 if (*r0kh_out
&& wpa_ft_rrb_init_r0kh_seq(*r0kh_out
) < 0)
1041 static int wpa_ft_rrb_init_r1kh_seq(struct ft_remote_r1kh
*r1kh
)
1046 r1kh
->seq
= os_zalloc(sizeof(*r1kh
->seq
));
1048 wpa_printf(MSG_DEBUG
, "FT: Failed to allocate r1kh->seq");
1052 dl_list_init(&r1kh
->seq
->rx
.queue
);
1058 static void wpa_ft_rrb_lookup_r1kh(struct wpa_authenticator
*wpa_auth
,
1059 const u8
*f_r1kh_id
,
1060 struct ft_remote_r1kh
**r1kh_out
,
1061 struct ft_remote_r1kh
**r1kh_wildcard
)
1063 struct ft_remote_r1kh
*r1kh
;
1065 *r1kh_wildcard
= NULL
;
1068 if (wpa_auth
->conf
.r1kh_list
)
1069 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1072 for (; r1kh
; r1kh
= r1kh
->next
) {
1073 if (is_zero_ether_addr(r1kh
->addr
) &&
1074 is_zero_ether_addr(r1kh
->id
))
1075 *r1kh_wildcard
= r1kh
;
1077 os_memcmp_const(r1kh
->id
, f_r1kh_id
, FT_R1KH_ID_LEN
) == 0)
1081 if (!*r1kh_out
&& !*r1kh_wildcard
)
1082 wpa_printf(MSG_DEBUG
, "FT: No matching R1KH found");
1084 if (*r1kh_out
&& wpa_ft_rrb_init_r1kh_seq(*r1kh_out
) < 0)
1089 static int wpa_ft_rrb_check_r0kh(struct wpa_authenticator
*wpa_auth
,
1090 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1092 if (f_r0kh_id_len
!= wpa_auth
->conf
.r0_key_holder_len
||
1093 os_memcmp_const(f_r0kh_id
, wpa_auth
->conf
.r0_key_holder
,
1094 f_r0kh_id_len
) != 0)
1101 static int wpa_ft_rrb_check_r1kh(struct wpa_authenticator
*wpa_auth
,
1102 const u8
*f_r1kh_id
)
1104 if (os_memcmp_const(f_r1kh_id
, wpa_auth
->conf
.r1_key_holder
,
1105 FT_R1KH_ID_LEN
) != 0)
1112 static void wpa_ft_rrb_del_r0kh(void *eloop_ctx
, void *timeout_ctx
)
1114 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1115 struct ft_remote_r0kh
*r0kh
, *prev
= NULL
;
1117 if (!wpa_auth
->conf
.r0kh_list
)
1120 for (r0kh
= *wpa_auth
->conf
.r0kh_list
; r0kh
; r0kh
= r0kh
->next
) {
1121 if (r0kh
== timeout_ctx
)
1128 prev
->next
= r0kh
->next
;
1130 *wpa_auth
->conf
.r0kh_list
= r0kh
->next
;
1132 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1138 static void wpa_ft_rrb_r0kh_replenish(struct wpa_authenticator
*wpa_auth
,
1139 struct ft_remote_r0kh
*r0kh
, int timeout
)
1142 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1147 static void wpa_ft_rrb_r0kh_timeout(struct wpa_authenticator
*wpa_auth
,
1148 struct ft_remote_r0kh
*r0kh
, int timeout
)
1150 eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
, r0kh
);
1153 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1158 static struct ft_remote_r0kh
*
1159 wpa_ft_rrb_add_r0kh(struct wpa_authenticator
*wpa_auth
,
1160 struct ft_remote_r0kh
*r0kh_wildcard
,
1161 const u8
*src_addr
, const u8
*r0kh_id
, size_t id_len
,
1164 struct ft_remote_r0kh
*r0kh
;
1166 if (!wpa_auth
->conf
.r0kh_list
)
1169 r0kh
= os_zalloc(sizeof(*r0kh
));
1174 os_memcpy(r0kh
->addr
, src_addr
, sizeof(r0kh
->addr
));
1176 if (id_len
> FT_R0KH_ID_MAX_LEN
)
1177 id_len
= FT_R0KH_ID_MAX_LEN
;
1178 os_memcpy(r0kh
->id
, r0kh_id
, id_len
);
1179 r0kh
->id_len
= id_len
;
1181 os_memcpy(r0kh
->key
, r0kh_wildcard
->key
, sizeof(r0kh
->key
));
1183 r0kh
->next
= *wpa_auth
->conf
.r0kh_list
;
1184 *wpa_auth
->conf
.r0kh_list
= r0kh
;
1187 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r0kh
,
1190 if (wpa_ft_rrb_init_r0kh_seq(r0kh
) < 0)
1197 static void wpa_ft_rrb_del_r1kh(void *eloop_ctx
, void *timeout_ctx
)
1199 struct wpa_authenticator
*wpa_auth
= eloop_ctx
;
1200 struct ft_remote_r1kh
*r1kh
, *prev
= NULL
;
1202 if (!wpa_auth
->conf
.r1kh_list
)
1205 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
1206 if (r1kh
== timeout_ctx
)
1213 prev
->next
= r1kh
->next
;
1215 *wpa_auth
->conf
.r1kh_list
= r1kh
->next
;
1217 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1223 static void wpa_ft_rrb_r1kh_replenish(struct wpa_authenticator
*wpa_auth
,
1224 struct ft_remote_r1kh
*r1kh
, int timeout
)
1227 eloop_replenish_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1232 static struct ft_remote_r1kh
*
1233 wpa_ft_rrb_add_r1kh(struct wpa_authenticator
*wpa_auth
,
1234 struct ft_remote_r1kh
*r1kh_wildcard
,
1235 const u8
*src_addr
, const u8
*r1kh_id
, int timeout
)
1237 struct ft_remote_r1kh
*r1kh
;
1239 if (!wpa_auth
->conf
.r1kh_list
)
1242 r1kh
= os_zalloc(sizeof(*r1kh
));
1246 os_memcpy(r1kh
->addr
, src_addr
, sizeof(r1kh
->addr
));
1247 os_memcpy(r1kh
->id
, r1kh_id
, sizeof(r1kh
->id
));
1248 os_memcpy(r1kh
->key
, r1kh_wildcard
->key
, sizeof(r1kh
->key
));
1249 r1kh
->next
= *wpa_auth
->conf
.r1kh_list
;
1250 *wpa_auth
->conf
.r1kh_list
= r1kh
;
1253 eloop_register_timeout(timeout
, 0, wpa_ft_rrb_del_r1kh
,
1256 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
1263 void wpa_ft_sta_deinit(struct wpa_state_machine
*sm
)
1265 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1269 static void wpa_ft_deinit_seq(struct wpa_authenticator
*wpa_auth
)
1271 struct ft_remote_r0kh
*r0kh
;
1272 struct ft_remote_r1kh
*r1kh
;
1274 eloop_cancel_timeout(wpa_ft_rrb_seq_timeout
, wpa_auth
, ELOOP_ALL_CTX
);
1276 if (wpa_auth
->conf
.r0kh_list
)
1277 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1280 for (; r0kh
; r0kh
= r0kh
->next
) {
1283 wpa_ft_rrb_seq_flush(wpa_auth
, r0kh
->seq
, 0);
1288 if (wpa_auth
->conf
.r1kh_list
)
1289 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1292 for (; r1kh
; r1kh
= r1kh
->next
) {
1295 wpa_ft_rrb_seq_flush(wpa_auth
, r1kh
->seq
, 0);
1302 static void wpa_ft_deinit_rkh_tmp(struct wpa_authenticator
*wpa_auth
)
1304 struct ft_remote_r0kh
*r0kh
, *r0kh_next
, *r0kh_prev
= NULL
;
1305 struct ft_remote_r1kh
*r1kh
, *r1kh_next
, *r1kh_prev
= NULL
;
1307 if (wpa_auth
->conf
.r0kh_list
)
1308 r0kh
= *wpa_auth
->conf
.r0kh_list
;
1312 r0kh_next
= r0kh
->next
;
1313 if (eloop_cancel_timeout(wpa_ft_rrb_del_r0kh
, wpa_auth
,
1316 r0kh_prev
->next
= r0kh_next
;
1318 *wpa_auth
->conf
.r0kh_list
= r0kh_next
;
1326 if (wpa_auth
->conf
.r1kh_list
)
1327 r1kh
= *wpa_auth
->conf
.r1kh_list
;
1331 r1kh_next
= r1kh
->next
;
1332 if (eloop_cancel_timeout(wpa_ft_rrb_del_r1kh
, wpa_auth
,
1335 r1kh_prev
->next
= r1kh_next
;
1337 *wpa_auth
->conf
.r1kh_list
= r1kh_next
;
1347 void wpa_ft_deinit(struct wpa_authenticator
*wpa_auth
)
1349 wpa_ft_deinit_seq(wpa_auth
);
1350 wpa_ft_deinit_rkh_tmp(wpa_auth
);
1354 static void wpa_ft_block_r0kh(struct wpa_authenticator
*wpa_auth
,
1355 const u8
*f_r0kh_id
, size_t f_r0kh_id_len
)
1357 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1359 if (!wpa_auth
->conf
.rkh_neg_timeout
)
1362 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
1363 &r0kh
, &r0kh_wildcard
);
1365 if (!r0kh_wildcard
) {
1366 /* r0kh removed after neg_timeout and might need re-adding */
1370 wpa_hexdump(MSG_DEBUG
, "FT: Blacklist R0KH-ID",
1371 f_r0kh_id
, f_r0kh_id_len
);
1374 wpa_ft_rrb_r0kh_timeout(wpa_auth
, r0kh
,
1375 wpa_auth
->conf
.rkh_neg_timeout
);
1376 os_memset(r0kh
->addr
, 0, ETH_ALEN
);
1378 wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, NULL
, f_r0kh_id
,
1380 wpa_auth
->conf
.rkh_neg_timeout
);
1384 static void wpa_ft_expire_pull(void *eloop_ctx
, void *timeout_ctx
)
1386 struct wpa_state_machine
*sm
= eloop_ctx
;
1388 wpa_printf(MSG_DEBUG
, "FT: Timeout pending pull request for " MACSTR
,
1390 if (sm
->ft_pending_pull_left_retries
<= 0)
1391 wpa_ft_block_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
);
1393 /* cancel multiple timeouts */
1394 eloop_cancel_timeout(wpa_ft_expire_pull
, sm
, NULL
);
1399 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine
*sm
,
1400 const u8
*ies
, size_t ies_len
,
1401 const u8
*pmk_r0_name
)
1403 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
1405 const u8
*key
, *f_r1kh_id
= sm
->wpa_auth
->conf
.r1_key_holder
;
1406 size_t packet_len
, key_len
;
1407 struct ft_rrb_seq f_seq
;
1408 int tsecs
, tusecs
, first
;
1409 struct wpabuf
*ft_pending_req_ies
;
1411 struct tlv_list req_enc
[] = {
1412 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
1413 .data
= pmk_r0_name
},
1414 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
1416 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1418 struct tlv_list req_auth
[] = {
1419 { .type
= FT_RRB_NONCE
, .len
= FT_RRB_NONCE_LEN
,
1420 .data
= sm
->ft_pending_pull_nonce
},
1421 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
1422 .data
= (u8
*) &f_seq
},
1423 { .type
= FT_RRB_R0KH_ID
, .len
= sm
->r0kh_id_len
,
1424 .data
= sm
->r0kh_id
},
1425 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
1426 .data
= f_r1kh_id
},
1427 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
1430 if (sm
->ft_pending_pull_left_retries
<= 0)
1432 first
= sm
->ft_pending_pull_left_retries
==
1433 sm
->wpa_auth
->conf
.rkh_pull_retries
;
1434 sm
->ft_pending_pull_left_retries
--;
1436 wpa_ft_rrb_lookup_r0kh(sm
->wpa_auth
, sm
->r0kh_id
, sm
->r0kh_id_len
,
1437 &r0kh
, &r0kh_wildcard
);
1439 /* Keep r0kh sufficiently long in the list for seq num check */
1440 r0kh_timeout
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000 +
1441 1 + ftRRBseqTimeout
;
1443 wpa_ft_rrb_r0kh_replenish(sm
->wpa_auth
, r0kh
, r0kh_timeout
);
1444 } else if (r0kh_wildcard
) {
1445 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
1446 /* r0kh->addr: updated by SEQ_RESP and wpa_ft_expire_pull */
1447 r0kh
= wpa_ft_rrb_add_r0kh(sm
->wpa_auth
, r0kh_wildcard
,
1448 r0kh_wildcard
->addr
,
1449 sm
->r0kh_id
, sm
->r0kh_id_len
,
1453 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
1454 sm
->r0kh_id
, sm
->r0kh_id_len
);
1457 if (is_zero_ether_addr(r0kh
->addr
)) {
1458 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID is blacklisted",
1459 sm
->r0kh_id
, sm
->r0kh_id_len
);
1462 if (os_memcmp(r0kh
->addr
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
1463 wpa_printf(MSG_DEBUG
,
1464 "FT: R0KH-ID points to self - no matching key available");
1469 key_len
= sizeof(r0kh
->key
);
1471 wpa_printf(MSG_DEBUG
, "FT: Send PMK-R1 pull request to remote R0KH "
1472 "address " MACSTR
, MAC2STR(r0kh
->addr
));
1474 if (r0kh
->seq
->rx
.num_last
== 0) {
1475 /* A sequence request will be sent out anyway when pull
1476 * response is received. Send it out now to avoid one RTT. */
1477 wpa_ft_rrb_seq_req(sm
->wpa_auth
, r0kh
->seq
, r0kh
->addr
,
1478 r0kh
->id
, r0kh
->id_len
, f_r1kh_id
, key
,
1479 key_len
, NULL
, 0, NULL
, 0, NULL
);
1483 random_get_bytes(sm
->ft_pending_pull_nonce
, FT_RRB_NONCE_LEN
) < 0) {
1484 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
1489 if (wpa_ft_new_seq(r0kh
->seq
, &f_seq
) < 0) {
1490 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
1494 if (wpa_ft_rrb_build(key
, key_len
, req_enc
, NULL
, req_auth
,
1495 sm
->wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1496 &packet
, &packet_len
) < 0)
1499 ft_pending_req_ies
= wpabuf_alloc_copy(ies
, ies_len
);
1500 wpabuf_free(sm
->ft_pending_req_ies
);
1501 sm
->ft_pending_req_ies
= ft_pending_req_ies
;
1502 if (!sm
->ft_pending_req_ies
) {
1507 tsecs
= sm
->wpa_auth
->conf
.rkh_pull_timeout
/ 1000;
1508 tusecs
= (sm
->wpa_auth
->conf
.rkh_pull_timeout
% 1000) * 1000;
1509 eloop_register_timeout(tsecs
, tusecs
, wpa_ft_expire_pull
, sm
, NULL
);
1511 wpa_ft_rrb_oui_send(sm
->wpa_auth
, r0kh
->addr
, FT_PACKET_R0KH_R1KH_PULL
,
1512 packet
, packet_len
);
1520 int wpa_auth_derive_ptk_ft(struct wpa_state_machine
*sm
, const u8
*pmk
,
1521 struct wpa_ptk
*ptk
)
1523 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
1525 u8 ptk_name
[WPA_PMK_NAME_LEN
];
1526 const u8
*mdid
= sm
->wpa_auth
->conf
.mobility_domain
;
1527 const u8
*r0kh
= sm
->wpa_auth
->conf
.r0_key_holder
;
1528 size_t r0kh_len
= sm
->wpa_auth
->conf
.r0_key_holder_len
;
1529 const u8
*r1kh
= sm
->wpa_auth
->conf
.r1_key_holder
;
1530 const u8
*ssid
= sm
->wpa_auth
->conf
.ssid
;
1531 size_t ssid_len
= sm
->wpa_auth
->conf
.ssid_len
;
1532 int psk_local
= sm
->wpa_auth
->conf
.ft_psk_generate_local
;
1534 if (sm
->xxkey_len
== 0) {
1535 wpa_printf(MSG_DEBUG
, "FT: XXKey not available for key "
1540 if (wpa_derive_pmk_r0(sm
->xxkey
, sm
->xxkey_len
, ssid
, ssid_len
, mdid
,
1541 r0kh
, r0kh_len
, sm
->addr
,
1542 pmk_r0
, pmk_r0_name
) < 0)
1544 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R0", pmk_r0
, PMK_LEN
);
1545 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", pmk_r0_name
, WPA_PMK_NAME_LEN
);
1546 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
1547 wpa_ft_store_pmk_r0(sm
->wpa_auth
, sm
->addr
, pmk_r0
, pmk_r0_name
,
1550 if (wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
1551 pmk_r1
, sm
->pmk_r1_name
) < 0)
1553 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
1554 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", sm
->pmk_r1_name
,
1556 if (!psk_local
|| !wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
))
1557 wpa_ft_store_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1
,
1558 sm
->pmk_r1_name
, sm
->pairwise
);
1560 return wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
1561 sm
->wpa_auth
->addr
, sm
->pmk_r1_name
,
1562 ptk
, ptk_name
, sm
->wpa_key_mgmt
, sm
->pairwise
);
1566 static inline int wpa_auth_get_seqnum(struct wpa_authenticator
*wpa_auth
,
1567 const u8
*addr
, int idx
, u8
*seq
)
1569 if (wpa_auth
->cb
->get_seqnum
== NULL
)
1571 return wpa_auth
->cb
->get_seqnum(wpa_auth
->cb_ctx
, addr
, idx
, seq
);
1575 static u8
* wpa_ft_gtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
1578 struct wpa_group
*gsm
= sm
->group
;
1579 size_t subelem_len
, pad_len
;
1584 key_len
= gsm
->GTK_len
;
1585 if (key_len
> sizeof(keybuf
))
1589 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
1592 pad_len
= key_len
% 8;
1594 pad_len
= 8 - pad_len
;
1595 if (key_len
+ pad_len
< 16)
1597 if (pad_len
&& key_len
< sizeof(keybuf
)) {
1598 os_memcpy(keybuf
, gsm
->GTK
[gsm
->GN
- 1], key_len
);
1599 os_memset(keybuf
+ key_len
, 0, pad_len
);
1600 keybuf
[key_len
] = 0xdd;
1604 key
= gsm
->GTK
[gsm
->GN
- 1];
1607 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
1610 subelem_len
= 13 + key_len
+ 8;
1611 subelem
= os_zalloc(subelem_len
);
1612 if (subelem
== NULL
)
1615 subelem
[0] = FTIE_SUBELEM_GTK
;
1616 subelem
[1] = 11 + key_len
+ 8;
1617 /* Key ID in B0-B1 of Key Info */
1618 WPA_PUT_LE16(&subelem
[2], gsm
->GN
& 0x03);
1619 subelem
[4] = gsm
->GTK_len
;
1620 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN
, subelem
+ 5);
1621 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, key_len
/ 8, key
,
1632 #ifdef CONFIG_IEEE80211W
1633 static u8
* wpa_ft_igtk_subelem(struct wpa_state_machine
*sm
, size_t *len
)
1636 struct wpa_group
*gsm
= sm
->group
;
1639 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
1641 subelem_len
= 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN
+ 8;
1642 subelem
= os_zalloc(subelem_len
);
1643 if (subelem
== NULL
)
1647 *pos
++ = FTIE_SUBELEM_IGTK
;
1648 *pos
++ = subelem_len
- 2;
1649 WPA_PUT_LE16(pos
, gsm
->GN_igtk
);
1651 wpa_auth_get_seqnum(sm
->wpa_auth
, NULL
, gsm
->GN_igtk
, pos
);
1653 *pos
++ = WPA_IGTK_LEN
;
1654 if (aes_wrap(sm
->PTK
.kek
, sm
->PTK
.kek_len
, WPA_IGTK_LEN
/ 8,
1655 gsm
->IGTK
[gsm
->GN_igtk
- 4], pos
)) {
1663 #endif /* CONFIG_IEEE80211W */
1666 static u8
* wpa_ft_process_rdie(struct wpa_state_machine
*sm
,
1667 u8
*pos
, u8
*end
, u8 id
, u8 descr_count
,
1668 const u8
*ies
, size_t ies_len
)
1670 struct ieee802_11_elems parse
;
1671 struct rsn_rdie
*rdie
;
1673 wpa_printf(MSG_DEBUG
, "FT: Resource Request: id=%d descr_count=%d",
1675 wpa_hexdump(MSG_MSGDUMP
, "FT: Resource descriptor IE(s)",
1678 if (end
- pos
< (int) sizeof(*rdie
)) {
1679 wpa_printf(MSG_ERROR
, "FT: Not enough room for response RDIE");
1683 *pos
++ = WLAN_EID_RIC_DATA
;
1684 *pos
++ = sizeof(*rdie
);
1685 rdie
= (struct rsn_rdie
*) pos
;
1687 rdie
->descr_count
= 0;
1688 rdie
->status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
1689 pos
+= sizeof(*rdie
);
1691 if (ieee802_11_parse_elems((u8
*) ies
, ies_len
, &parse
, 1) ==
1693 wpa_printf(MSG_DEBUG
, "FT: Failed to parse request IEs");
1695 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
1699 if (parse
.wmm_tspec
) {
1700 struct wmm_tspec_element
*tspec
;
1702 if (parse
.wmm_tspec_len
+ 2 < (int) sizeof(*tspec
)) {
1703 wpa_printf(MSG_DEBUG
, "FT: Too short WMM TSPEC IE "
1704 "(%d)", (int) parse
.wmm_tspec_len
);
1706 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
1709 if (end
- pos
< (int) sizeof(*tspec
)) {
1710 wpa_printf(MSG_ERROR
, "FT: Not enough room for "
1713 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
1716 tspec
= (struct wmm_tspec_element
*) pos
;
1717 os_memcpy(tspec
, parse
.wmm_tspec
- 2, sizeof(*tspec
));
1721 if (parse
.wmm_tspec
&& sm
->wpa_auth
->conf
.ap_mlme
) {
1724 res
= wmm_process_tspec((struct wmm_tspec_element
*) pos
);
1725 wpa_printf(MSG_DEBUG
, "FT: ADDTS processing result: %d", res
);
1726 if (res
== WMM_ADDTS_STATUS_INVALID_PARAMETERS
)
1728 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS
);
1729 else if (res
== WMM_ADDTS_STATUS_REFUSED
)
1731 host_to_le16(WLAN_STATUS_REQUEST_DECLINED
);
1733 /* TSPEC accepted; include updated TSPEC in response */
1734 rdie
->descr_count
= 1;
1735 pos
+= sizeof(struct wmm_tspec_element
);
1739 #endif /* NEED_AP_MLME */
1741 if (parse
.wmm_tspec
&& !sm
->wpa_auth
->conf
.ap_mlme
) {
1744 res
= wpa_ft_add_tspec(sm
->wpa_auth
, sm
->addr
, pos
,
1745 sizeof(struct wmm_tspec_element
));
1748 rdie
->status_code
= host_to_le16(res
);
1750 /* TSPEC accepted; include updated TSPEC in
1752 rdie
->descr_count
= 1;
1753 pos
+= sizeof(struct wmm_tspec_element
);
1759 wpa_printf(MSG_DEBUG
, "FT: No supported resource requested");
1760 rdie
->status_code
= host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE
);
1765 static u8
* wpa_ft_process_ric(struct wpa_state_machine
*sm
, u8
*pos
, u8
*end
,
1766 const u8
*ric
, size_t ric_len
)
1768 const u8
*rpos
, *start
;
1769 const struct rsn_rdie
*rdie
;
1771 wpa_hexdump(MSG_MSGDUMP
, "FT: RIC Request", ric
, ric_len
);
1774 while (rpos
+ sizeof(*rdie
) < ric
+ ric_len
) {
1775 if (rpos
[0] != WLAN_EID_RIC_DATA
|| rpos
[1] < sizeof(*rdie
) ||
1776 rpos
+ 2 + rpos
[1] > ric
+ ric_len
)
1778 rdie
= (const struct rsn_rdie
*) (rpos
+ 2);
1779 rpos
+= 2 + rpos
[1];
1782 while (rpos
+ 2 <= ric
+ ric_len
&&
1783 rpos
+ 2 + rpos
[1] <= ric
+ ric_len
) {
1784 if (rpos
[0] == WLAN_EID_RIC_DATA
)
1786 rpos
+= 2 + rpos
[1];
1788 pos
= wpa_ft_process_rdie(sm
, pos
, end
, rdie
->id
,
1790 start
, rpos
- start
);
1797 u8
* wpa_sm_write_assoc_resp_ies(struct wpa_state_machine
*sm
, u8
*pos
,
1798 size_t max_len
, int auth_alg
,
1799 const u8
*req_ies
, size_t req_ies_len
)
1801 u8
*end
, *mdie
, *ftie
, *rsnie
= NULL
, *r0kh_id
, *subelem
= NULL
;
1802 size_t mdie_len
, ftie_len
, rsnie_len
= 0, r0kh_id_len
, subelem_len
= 0;
1804 struct wpa_auth_config
*conf
;
1805 struct rsn_ftie
*_ftie
;
1806 struct wpa_ft_ies parse
;
1808 u8
*anonce
, *snonce
;
1815 conf
= &sm
->wpa_auth
->conf
;
1817 if (!wpa_key_mgmt_ft(sm
->wpa_key_mgmt
))
1820 end
= pos
+ max_len
;
1822 if (auth_alg
== WLAN_AUTH_FT
) {
1824 * RSN (only present if this is a Reassociation Response and
1825 * part of a fast BSS transition)
1827 res
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, sm
->pmk_r1_name
);
1835 /* Mobility Domain Information */
1836 res
= wpa_write_mdie(conf
, pos
, end
- pos
);
1843 /* Fast BSS Transition Information */
1844 if (auth_alg
== WLAN_AUTH_FT
) {
1845 subelem
= wpa_ft_gtk_subelem(sm
, &subelem_len
);
1846 r0kh_id
= sm
->r0kh_id
;
1847 r0kh_id_len
= sm
->r0kh_id_len
;
1848 anonce
= sm
->ANonce
;
1849 snonce
= sm
->SNonce
;
1850 #ifdef CONFIG_IEEE80211W
1851 if (sm
->mgmt_frame_prot
) {
1855 igtk
= wpa_ft_igtk_subelem(sm
, &igtk_len
);
1860 nbuf
= os_realloc(subelem
, subelem_len
+ igtk_len
);
1867 os_memcpy(subelem
+ subelem_len
, igtk
, igtk_len
);
1868 subelem_len
+= igtk_len
;
1871 #endif /* CONFIG_IEEE80211W */
1873 r0kh_id
= conf
->r0_key_holder
;
1874 r0kh_id_len
= conf
->r0_key_holder_len
;
1878 res
= wpa_write_ftie(conf
, r0kh_id
, r0kh_id_len
, anonce
, snonce
, pos
,
1879 end
- pos
, subelem
, subelem_len
);
1887 _ftie
= (struct rsn_ftie
*) (ftie
+ 2);
1888 if (auth_alg
== WLAN_AUTH_FT
)
1889 _ftie
->mic_control
[1] = 3; /* Information element count */
1892 if (wpa_ft_parse_ies(req_ies
, req_ies_len
, &parse
) == 0 && parse
.ric
) {
1893 pos
= wpa_ft_process_ric(sm
, pos
, end
, parse
.ric
,
1895 if (auth_alg
== WLAN_AUTH_FT
)
1896 _ftie
->mic_control
[1] +=
1897 ieee802_11_ie_count(ric_start
,
1900 if (ric_start
== pos
)
1903 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
1905 kck_len
= sm
->PTK
.kck2_len
;
1908 kck_len
= sm
->PTK
.kck_len
;
1910 if (auth_alg
== WLAN_AUTH_FT
&&
1911 wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 6,
1912 mdie
, mdie_len
, ftie
, ftie_len
,
1914 ric_start
, ric_start
? pos
- ric_start
: 0,
1916 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
1918 os_free(sm
->assoc_resp_ftie
);
1919 sm
->assoc_resp_ftie
= os_malloc(ftie_len
);
1920 if (sm
->assoc_resp_ftie
)
1921 os_memcpy(sm
->assoc_resp_ftie
, ftie
, ftie_len
);
1927 static inline int wpa_auth_set_key(struct wpa_authenticator
*wpa_auth
,
1929 enum wpa_alg alg
, const u8
*addr
, int idx
,
1930 u8
*key
, size_t key_len
)
1932 if (wpa_auth
->cb
->set_key
== NULL
)
1934 return wpa_auth
->cb
->set_key(wpa_auth
->cb_ctx
, vlan_id
, alg
, addr
, idx
,
1939 void wpa_ft_install_ptk(struct wpa_state_machine
*sm
)
1944 /* MLME-SETKEYS.request(PTK) */
1945 alg
= wpa_cipher_to_alg(sm
->pairwise
);
1946 klen
= wpa_cipher_key_len(sm
->pairwise
);
1947 if (!wpa_cipher_valid_pairwise(sm
->pairwise
)) {
1948 wpa_printf(MSG_DEBUG
, "FT: Unknown pairwise alg 0x%x - skip "
1949 "PTK configuration", sm
->pairwise
);
1953 if (sm
->tk_already_set
) {
1954 /* Must avoid TK reconfiguration to prevent clearing of TX/RX
1955 * PN in the driver */
1956 wpa_printf(MSG_DEBUG
,
1957 "FT: Do not re-install same PTK to the driver");
1961 /* FIX: add STA entry to kernel/driver here? The set_key will fail
1962 * most likely without this.. At the moment, STA entry is added only
1963 * after association has been completed. This function will be called
1964 * again after association to get the PTK configured, but that could be
1965 * optimized by adding the STA entry earlier.
1967 if (wpa_auth_set_key(sm
->wpa_auth
, 0, alg
, sm
->addr
, 0,
1971 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
1972 sm
->pairwise_set
= TRUE
;
1973 sm
->tk_already_set
= TRUE
;
1977 /* Derive PMK-R1 from PSK, check all available PSK */
1978 static int wpa_ft_psk_pmk_r1(struct wpa_state_machine
*sm
,
1979 const u8
*req_pmk_r1_name
,
1980 u8
*out_pmk_r1
, int *out_pairwise
)
1982 const u8
*pmk
= NULL
;
1983 u8 pmk_r0
[PMK_LEN
], pmk_r0_name
[WPA_PMK_NAME_LEN
];
1984 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
1985 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
1986 const u8
*mdid
= wpa_auth
->conf
.mobility_domain
;
1987 const u8
*r0kh
= sm
->r0kh_id
;
1988 size_t r0kh_len
= sm
->r0kh_id_len
;
1989 const u8
*r1kh
= wpa_auth
->conf
.r1_key_holder
;
1990 const u8
*ssid
= wpa_auth
->conf
.ssid
;
1991 size_t ssid_len
= wpa_auth
->conf
.ssid_len
;
1994 pairwise
= sm
->pairwise
;
1997 pmk
= wpa_ft_get_psk(wpa_auth
, sm
->addr
, sm
->p2p_dev_addr
,
2002 if (wpa_derive_pmk_r0(pmk
, PMK_LEN
, ssid
, ssid_len
, mdid
, r0kh
,
2004 pmk_r0
, pmk_r0_name
) < 0 ||
2005 wpa_derive_pmk_r1(pmk_r0
, pmk_r0_name
, r1kh
, sm
->addr
,
2006 pmk_r1
, pmk_r1_name
) < 0 ||
2007 os_memcmp_const(pmk_r1_name
, req_pmk_r1_name
,
2008 WPA_PMK_NAME_LEN
) != 0)
2011 /* We found a PSK that matches the requested pmk_r1_name */
2012 wpa_printf(MSG_DEBUG
,
2013 "FT: Found PSK to generate PMK-R1 locally");
2014 os_memcpy(out_pmk_r1
, pmk_r1
, PMK_LEN
);
2016 *out_pairwise
= pairwise
;
2020 wpa_printf(MSG_DEBUG
,
2021 "FT: Did not find PSK to generate PMK-R1 locally");
2026 /* Detect the configuration the station asked for.
2027 * Required to detect FT-PSK and pairwise cipher.
2029 static int wpa_ft_set_key_mgmt(struct wpa_state_machine
*sm
,
2030 struct wpa_ft_ies
*parse
)
2032 int key_mgmt
, ciphers
;
2034 if (sm
->wpa_key_mgmt
)
2037 key_mgmt
= parse
->key_mgmt
& sm
->wpa_auth
->conf
.wpa_key_mgmt
;
2039 wpa_printf(MSG_DEBUG
, "FT: Invalid key mgmt (0x%x) from "
2040 MACSTR
, parse
->key_mgmt
, MAC2STR(sm
->addr
));
2043 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
2044 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_IEEE8021X
;
2045 else if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
2046 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_PSK
;
2048 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA256
)
2049 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA256
;
2050 else if (key_mgmt
& WPA_KEY_MGMT_FT_FILS_SHA384
)
2051 sm
->wpa_key_mgmt
= WPA_KEY_MGMT_FT_FILS_SHA384
;
2052 #endif /* CONFIG_FILS */
2053 ciphers
= parse
->pairwise_cipher
& sm
->wpa_auth
->conf
.rsn_pairwise
;
2055 wpa_printf(MSG_DEBUG
, "FT: Invalid pairwise cipher (0x%x) from "
2057 parse
->pairwise_cipher
, MAC2STR(sm
->addr
));
2060 sm
->pairwise
= wpa_pick_pairwise_cipher(ciphers
, 0);
2066 static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator
*wpa_auth
,
2067 struct wpa_state_machine
*sm
,
2068 const u8
*r0kh_id
, size_t r0kh_id_len
,
2069 const u8
*req_pmk_r0_name
,
2070 const u8
*req_pmk_r1_name
,
2071 u8
*out_pmk_r1
, int *out_pairwise
)
2073 struct wpa_auth_config
*conf
= &wpa_auth
->conf
;
2074 const struct wpa_ft_pmk_r0_sa
*r0
;
2075 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2077 if (conf
->r0_key_holder_len
!= r0kh_id_len
||
2078 os_memcmp(conf
->r0_key_holder
, r0kh_id
, conf
->r0_key_holder_len
) !=
2080 return -1; /* not our R0KH-ID */
2082 wpa_printf(MSG_DEBUG
, "FT: STA R0KH-ID matching local configuration");
2083 if (wpa_ft_fetch_pmk_r0(sm
->wpa_auth
, sm
->addr
, req_pmk_r0_name
, &r0
) <
2085 return -1; /* no matching PMKR0Name in local cache */
2087 wpa_printf(MSG_DEBUG
, "FT: Requested PMKR0Name found in local cache");
2089 if (wpa_derive_pmk_r1(r0
->pmk_r0
, r0
->pmk_r0_name
, conf
->r1_key_holder
,
2090 sm
->addr
, out_pmk_r1
, pmk_r1_name
) < 0)
2092 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", out_pmk_r1
, PMK_LEN
);
2093 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2095 wpa_ft_store_pmk_r1(wpa_auth
, sm
->addr
, out_pmk_r1
, pmk_r1_name
,
2098 *out_pairwise
= sm
->pairwise
;
2103 static int wpa_ft_process_auth_req(struct wpa_state_machine
*sm
,
2104 const u8
*ies
, size_t ies_len
,
2105 u8
**resp_ies
, size_t *resp_ies_len
)
2107 struct rsn_mdie
*mdie
;
2108 struct rsn_ftie
*ftie
;
2109 u8 pmk_r1
[PMK_LEN
], pmk_r1_name
[WPA_PMK_NAME_LEN
];
2110 u8 ptk_name
[WPA_PMK_NAME_LEN
];
2111 struct wpa_auth_config
*conf
;
2112 struct wpa_ft_ies parse
;
2121 sm
->pmk_r1_name_valid
= 0;
2122 conf
= &sm
->wpa_auth
->conf
;
2124 wpa_hexdump(MSG_DEBUG
, "FT: Received authentication frame IEs",
2127 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2128 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2129 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2132 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2133 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2134 os_memcmp(mdie
->mobility_domain
,
2135 sm
->wpa_auth
->conf
.mobility_domain
,
2136 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2137 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2138 return WLAN_STATUS_INVALID_MDIE
;
2141 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2142 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2143 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2144 return WLAN_STATUS_INVALID_FTIE
;
2147 os_memcpy(sm
->SNonce
, ftie
->snonce
, WPA_NONCE_LEN
);
2149 if (parse
.r0kh_id
== NULL
) {
2150 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE - no R0KH-ID");
2151 return WLAN_STATUS_INVALID_FTIE
;
2154 wpa_hexdump(MSG_DEBUG
, "FT: STA R0KH-ID",
2155 parse
.r0kh_id
, parse
.r0kh_id_len
);
2156 os_memcpy(sm
->r0kh_id
, parse
.r0kh_id
, parse
.r0kh_id_len
);
2157 sm
->r0kh_id_len
= parse
.r0kh_id_len
;
2159 if (parse
.rsn_pmkid
== NULL
) {
2160 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2161 return WLAN_STATUS_INVALID_PMKID
;
2164 if (wpa_ft_set_key_mgmt(sm
, &parse
) < 0)
2165 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2167 wpa_hexdump(MSG_DEBUG
, "FT: Requested PMKR0Name",
2168 parse
.rsn_pmkid
, WPA_PMK_NAME_LEN
);
2169 if (wpa_derive_pmk_r1_name(parse
.rsn_pmkid
,
2170 sm
->wpa_auth
->conf
.r1_key_holder
, sm
->addr
,
2172 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2173 wpa_hexdump(MSG_DEBUG
, "FT: Derived requested PMKR1Name",
2174 pmk_r1_name
, WPA_PMK_NAME_LEN
);
2176 if (conf
->ft_psk_generate_local
&&
2177 wpa_key_mgmt_ft_psk(sm
->wpa_key_mgmt
)) {
2178 if (wpa_ft_psk_pmk_r1(sm
, pmk_r1_name
, pmk_r1
, &pairwise
) < 0)
2179 return WLAN_STATUS_INVALID_PMKID
;
2180 wpa_printf(MSG_DEBUG
,
2181 "FT: Generated PMK-R1 for FT-PSK locally");
2182 } else if (wpa_ft_fetch_pmk_r1(sm
->wpa_auth
, sm
->addr
, pmk_r1_name
,
2183 pmk_r1
, &pairwise
) < 0) {
2184 wpa_printf(MSG_DEBUG
,
2185 "FT: No PMK-R1 available in local cache for the requested PMKR1Name");
2186 if (wpa_ft_local_derive_pmk_r1(sm
->wpa_auth
, sm
,
2187 parse
.r0kh_id
, parse
.r0kh_id_len
,
2189 pmk_r1_name
, pmk_r1
, &pairwise
)
2191 wpa_printf(MSG_DEBUG
,
2192 "FT: Generated PMK-R1 based on local PMK-R0");
2193 goto pmk_r1_derived
;
2196 if (wpa_ft_pull_pmk_r1(sm
, ies
, ies_len
, parse
.rsn_pmkid
) < 0) {
2197 wpa_printf(MSG_DEBUG
,
2198 "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH");
2199 return WLAN_STATUS_INVALID_PMKID
;
2202 return -1; /* Status pending */
2204 wpa_printf(MSG_DEBUG
, "FT: Found PMKR1Name from local cache");
2208 wpa_hexdump_key(MSG_DEBUG
, "FT: Selected PMK-R1", pmk_r1
, PMK_LEN
);
2209 sm
->pmk_r1_name_valid
= 1;
2210 os_memcpy(sm
->pmk_r1_name
, pmk_r1_name
, WPA_PMK_NAME_LEN
);
2212 if (random_get_bytes(sm
->ANonce
, WPA_NONCE_LEN
)) {
2213 wpa_printf(MSG_DEBUG
, "FT: Failed to get random data for "
2215 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2218 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2219 sm
->SNonce
, WPA_NONCE_LEN
);
2220 wpa_hexdump(MSG_DEBUG
, "FT: Generated ANonce",
2221 sm
->ANonce
, WPA_NONCE_LEN
);
2223 if (wpa_pmk_r1_to_ptk(pmk_r1
, sm
->SNonce
, sm
->ANonce
, sm
->addr
,
2224 sm
->wpa_auth
->addr
, pmk_r1_name
,
2225 &sm
->PTK
, ptk_name
, sm
->wpa_key_mgmt
,
2227 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2229 sm
->pairwise
= pairwise
;
2230 sm
->PTK_valid
= TRUE
;
2231 sm
->tk_already_set
= FALSE
;
2232 wpa_ft_install_ptk(sm
);
2234 buflen
= 2 + sizeof(struct rsn_mdie
) + 2 + sizeof(struct rsn_ftie
) +
2235 2 + FT_R1KH_ID_LEN
+ 200;
2236 *resp_ies
= os_zalloc(buflen
);
2237 if (*resp_ies
== NULL
)
2241 end
= *resp_ies
+ buflen
;
2243 ret
= wpa_write_rsn_ie(conf
, pos
, end
- pos
, parse
.rsn_pmkid
);
2248 ret
= wpa_write_mdie(conf
, pos
, end
- pos
);
2253 ret
= wpa_write_ftie(conf
, parse
.r0kh_id
, parse
.r0kh_id_len
,
2254 sm
->ANonce
, sm
->SNonce
, pos
, end
- pos
, NULL
, 0);
2259 *resp_ies_len
= pos
- *resp_ies
;
2261 return WLAN_STATUS_SUCCESS
;
2265 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2269 void wpa_ft_process_auth(struct wpa_state_machine
*sm
, const u8
*bssid
,
2270 u16 auth_transaction
, const u8
*ies
, size_t ies_len
,
2271 void (*cb
)(void *ctx
, const u8
*dst
, const u8
*bssid
,
2272 u16 auth_transaction
, u16 status
,
2273 const u8
*ies
, size_t ies_len
),
2278 size_t resp_ies_len
;
2282 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame, but "
2283 "WPA SM not available");
2287 wpa_printf(MSG_DEBUG
, "FT: Received authentication frame: STA=" MACSTR
2288 " BSSID=" MACSTR
" transaction=%d",
2289 MAC2STR(sm
->addr
), MAC2STR(bssid
), auth_transaction
);
2290 sm
->ft_pending_cb
= cb
;
2291 sm
->ft_pending_cb_ctx
= ctx
;
2292 sm
->ft_pending_auth_transaction
= auth_transaction
;
2293 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2294 res
= wpa_ft_process_auth_req(sm
, ies
, ies_len
, &resp_ies
,
2297 wpa_printf(MSG_DEBUG
, "FT: Callback postponed until response is available");
2302 wpa_printf(MSG_DEBUG
, "FT: FT authentication response: dst=" MACSTR
2303 " auth_transaction=%d status=%d",
2304 MAC2STR(sm
->addr
), auth_transaction
+ 1, status
);
2305 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2306 cb(ctx
, sm
->addr
, bssid
, auth_transaction
+ 1, status
,
2307 resp_ies
, resp_ies_len
);
2312 u16
wpa_ft_validate_reassoc(struct wpa_state_machine
*sm
, const u8
*ies
,
2315 struct wpa_ft_ies parse
;
2316 struct rsn_mdie
*mdie
;
2317 struct rsn_ftie
*ftie
;
2318 u8 mic
[WPA_EAPOL_KEY_MIC_MAX_LEN
];
2319 size_t mic_len
= 16;
2325 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2327 wpa_hexdump(MSG_DEBUG
, "FT: Reassoc Req IEs", ies
, ies_len
);
2329 if (wpa_ft_parse_ies(ies
, ies_len
, &parse
) < 0) {
2330 wpa_printf(MSG_DEBUG
, "FT: Failed to parse FT IEs");
2331 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2334 if (parse
.rsn
== NULL
) {
2335 wpa_printf(MSG_DEBUG
, "FT: No RSNIE in Reassoc Req");
2336 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2339 if (parse
.rsn_pmkid
== NULL
) {
2340 wpa_printf(MSG_DEBUG
, "FT: No PMKID in RSNIE");
2341 return WLAN_STATUS_INVALID_PMKID
;
2344 if (os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
)
2346 wpa_printf(MSG_DEBUG
, "FT: PMKID in Reassoc Req did not match "
2347 "with the PMKR1Name derived from auth request");
2348 return WLAN_STATUS_INVALID_PMKID
;
2351 mdie
= (struct rsn_mdie
*) parse
.mdie
;
2352 if (mdie
== NULL
|| parse
.mdie_len
< sizeof(*mdie
) ||
2353 os_memcmp(mdie
->mobility_domain
,
2354 sm
->wpa_auth
->conf
.mobility_domain
,
2355 MOBILITY_DOMAIN_ID_LEN
) != 0) {
2356 wpa_printf(MSG_DEBUG
, "FT: Invalid MDIE");
2357 return WLAN_STATUS_INVALID_MDIE
;
2360 ftie
= (struct rsn_ftie
*) parse
.ftie
;
2361 if (ftie
== NULL
|| parse
.ftie_len
< sizeof(*ftie
)) {
2362 wpa_printf(MSG_DEBUG
, "FT: Invalid FTIE");
2363 return WLAN_STATUS_INVALID_FTIE
;
2366 if (os_memcmp(ftie
->snonce
, sm
->SNonce
, WPA_NONCE_LEN
) != 0) {
2367 wpa_printf(MSG_DEBUG
, "FT: SNonce mismatch in FTIE");
2368 wpa_hexdump(MSG_DEBUG
, "FT: Received SNonce",
2369 ftie
->snonce
, WPA_NONCE_LEN
);
2370 wpa_hexdump(MSG_DEBUG
, "FT: Expected SNonce",
2371 sm
->SNonce
, WPA_NONCE_LEN
);
2372 return WLAN_STATUS_INVALID_FTIE
;
2375 if (os_memcmp(ftie
->anonce
, sm
->ANonce
, WPA_NONCE_LEN
) != 0) {
2376 wpa_printf(MSG_DEBUG
, "FT: ANonce mismatch in FTIE");
2377 wpa_hexdump(MSG_DEBUG
, "FT: Received ANonce",
2378 ftie
->anonce
, WPA_NONCE_LEN
);
2379 wpa_hexdump(MSG_DEBUG
, "FT: Expected ANonce",
2380 sm
->ANonce
, WPA_NONCE_LEN
);
2381 return WLAN_STATUS_INVALID_FTIE
;
2385 if (parse
.r0kh_id
== NULL
) {
2386 wpa_printf(MSG_DEBUG
, "FT: No R0KH-ID subelem in FTIE");
2387 return WLAN_STATUS_INVALID_FTIE
;
2390 if (parse
.r0kh_id_len
!= sm
->r0kh_id_len
||
2391 os_memcmp_const(parse
.r0kh_id
, sm
->r0kh_id
, parse
.r0kh_id_len
) != 0)
2393 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID in FTIE did not match with "
2394 "the current R0KH-ID");
2395 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID in FTIE",
2396 parse
.r0kh_id
, parse
.r0kh_id_len
);
2397 wpa_hexdump(MSG_DEBUG
, "FT: The current R0KH-ID",
2398 sm
->r0kh_id
, sm
->r0kh_id_len
);
2399 return WLAN_STATUS_INVALID_FTIE
;
2402 if (parse
.r1kh_id
== NULL
) {
2403 wpa_printf(MSG_DEBUG
, "FT: No R1KH-ID subelem in FTIE");
2404 return WLAN_STATUS_INVALID_FTIE
;
2407 if (os_memcmp_const(parse
.r1kh_id
, sm
->wpa_auth
->conf
.r1_key_holder
,
2408 FT_R1KH_ID_LEN
) != 0) {
2409 wpa_printf(MSG_DEBUG
, "FT: Unknown R1KH-ID used in "
2411 wpa_hexdump(MSG_DEBUG
, "FT: R1KH-ID in FTIE",
2412 parse
.r1kh_id
, FT_R1KH_ID_LEN
);
2413 wpa_hexdump(MSG_DEBUG
, "FT: Expected R1KH-ID",
2414 sm
->wpa_auth
->conf
.r1_key_holder
, FT_R1KH_ID_LEN
);
2415 return WLAN_STATUS_INVALID_FTIE
;
2418 if (parse
.rsn_pmkid
== NULL
||
2419 os_memcmp_const(parse
.rsn_pmkid
, sm
->pmk_r1_name
, WPA_PMK_NAME_LEN
))
2421 wpa_printf(MSG_DEBUG
, "FT: No matching PMKR1Name (PMKID) in "
2422 "RSNIE (pmkid=%d)", !!parse
.rsn_pmkid
);
2423 return WLAN_STATUS_INVALID_PMKID
;
2428 count
+= ieee802_11_ie_count(parse
.ric
, parse
.ric_len
);
2429 if (ftie
->mic_control
[1] != count
) {
2430 wpa_printf(MSG_DEBUG
, "FT: Unexpected IE count in MIC "
2431 "Control: received %u expected %u",
2432 ftie
->mic_control
[1], count
);
2433 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2436 if (wpa_key_mgmt_fils(sm
->wpa_key_mgmt
)) {
2438 kck_len
= sm
->PTK
.kck2_len
;
2441 kck_len
= sm
->PTK
.kck_len
;
2443 if (wpa_ft_mic(kck
, kck_len
, sm
->addr
, sm
->wpa_auth
->addr
, 5,
2444 parse
.mdie
- 2, parse
.mdie_len
+ 2,
2445 parse
.ftie
- 2, parse
.ftie_len
+ 2,
2446 parse
.rsn
- 2, parse
.rsn_len
+ 2,
2447 parse
.ric
, parse
.ric_len
,
2449 wpa_printf(MSG_DEBUG
, "FT: Failed to calculate MIC");
2450 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2453 if (os_memcmp_const(mic
, ftie
->mic
, mic_len
) != 0) {
2454 wpa_printf(MSG_DEBUG
, "FT: Invalid MIC in FTIE");
2455 wpa_printf(MSG_DEBUG
, "FT: addr=" MACSTR
" auth_addr=" MACSTR
,
2456 MAC2STR(sm
->addr
), MAC2STR(sm
->wpa_auth
->addr
));
2457 wpa_hexdump(MSG_MSGDUMP
, "FT: Received MIC",
2458 ftie
->mic
, mic_len
);
2459 wpa_hexdump(MSG_MSGDUMP
, "FT: Calculated MIC", mic
, mic_len
);
2460 wpa_hexdump(MSG_MSGDUMP
, "FT: MDIE",
2461 parse
.mdie
- 2, parse
.mdie_len
+ 2);
2462 wpa_hexdump(MSG_MSGDUMP
, "FT: FTIE",
2463 parse
.ftie
- 2, parse
.ftie_len
+ 2);
2464 wpa_hexdump(MSG_MSGDUMP
, "FT: RSN",
2465 parse
.rsn
- 2, parse
.rsn_len
+ 2);
2466 return WLAN_STATUS_INVALID_FTIE
;
2469 return WLAN_STATUS_SUCCESS
;
2473 int wpa_ft_action_rx(struct wpa_state_machine
*sm
, const u8
*data
, size_t len
)
2475 const u8
*sta_addr
, *target_ap
;
2479 struct ft_rrb_frame
*frame
;
2485 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
2486 * FT Request action frame body[variable]
2490 wpa_printf(MSG_DEBUG
, "FT: Too short FT Action frame "
2491 "(len=%lu)", (unsigned long) len
);
2496 sta_addr
= data
+ 2;
2497 target_ap
= data
+ 8;
2501 wpa_printf(MSG_DEBUG
, "FT: Received FT Action frame (STA=" MACSTR
2502 " Target AP=" MACSTR
" Action=%d)",
2503 MAC2STR(sta_addr
), MAC2STR(target_ap
), action
);
2505 if (os_memcmp(sta_addr
, sm
->addr
, ETH_ALEN
) != 0) {
2506 wpa_printf(MSG_DEBUG
, "FT: Mismatch in FT Action STA address: "
2507 "STA=" MACSTR
" STA-Address=" MACSTR
,
2508 MAC2STR(sm
->addr
), MAC2STR(sta_addr
));
2513 * Do some sanity checking on the target AP address (not own and not
2514 * broadcast. This could be extended to filter based on a list of known
2515 * APs in the MD (if such a list were configured).
2517 if ((target_ap
[0] & 0x01) ||
2518 os_memcmp(target_ap
, sm
->wpa_auth
->addr
, ETH_ALEN
) == 0) {
2519 wpa_printf(MSG_DEBUG
, "FT: Invalid Target AP in FT Action "
2524 wpa_hexdump(MSG_MSGDUMP
, "FT: Action frame body", ies
, ies_len
);
2526 if (!sm
->wpa_auth
->conf
.ft_over_ds
) {
2527 wpa_printf(MSG_DEBUG
, "FT: Over-DS option disabled - reject");
2531 /* RRB - Forward action frame to the target AP */
2532 frame
= os_malloc(sizeof(*frame
) + len
);
2535 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
2536 frame
->packet_type
= FT_PACKET_REQUEST
;
2537 frame
->action_length
= host_to_le16(len
);
2538 os_memcpy(frame
->ap_address
, sm
->wpa_auth
->addr
, ETH_ALEN
);
2539 os_memcpy(frame
+ 1, data
, len
);
2541 wpa_ft_rrb_send(sm
->wpa_auth
, target_ap
, (u8
*) frame
,
2542 sizeof(*frame
) + len
);
2549 static void wpa_ft_rrb_rx_request_cb(void *ctx
, const u8
*dst
, const u8
*bssid
,
2550 u16 auth_transaction
, u16 resp
,
2551 const u8
*ies
, size_t ies_len
)
2553 struct wpa_state_machine
*sm
= ctx
;
2554 wpa_printf(MSG_DEBUG
, "FT: Over-the-DS RX request cb for " MACSTR
,
2556 wpa_ft_send_rrb_auth_resp(sm
, sm
->ft_pending_current_ap
, sm
->addr
,
2557 WLAN_STATUS_SUCCESS
, ies
, ies_len
);
2561 static int wpa_ft_rrb_rx_request(struct wpa_authenticator
*wpa_auth
,
2562 const u8
*current_ap
, const u8
*sta_addr
,
2563 const u8
*body
, size_t len
)
2565 struct wpa_state_machine
*sm
;
2568 size_t resp_ies_len
;
2571 sm
= wpa_ft_add_sta(wpa_auth
, sta_addr
);
2573 wpa_printf(MSG_DEBUG
, "FT: Failed to add new STA based on "
2578 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB Request Frame body", body
, len
);
2580 sm
->ft_pending_cb
= wpa_ft_rrb_rx_request_cb
;
2581 sm
->ft_pending_cb_ctx
= sm
;
2582 os_memcpy(sm
->ft_pending_current_ap
, current_ap
, ETH_ALEN
);
2583 sm
->ft_pending_pull_left_retries
= sm
->wpa_auth
->conf
.rkh_pull_retries
;
2584 res
= wpa_ft_process_auth_req(sm
, body
, len
, &resp_ies
,
2587 wpa_printf(MSG_DEBUG
, "FT: No immediate response available - wait for pull response");
2592 res
= wpa_ft_send_rrb_auth_resp(sm
, current_ap
, sta_addr
, status
,
2593 resp_ies
, resp_ies_len
);
2599 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine
*sm
,
2600 const u8
*current_ap
, const u8
*sta_addr
,
2601 u16 status
, const u8
*resp_ies
,
2602 size_t resp_ies_len
)
2604 struct wpa_authenticator
*wpa_auth
= sm
->wpa_auth
;
2606 struct ft_rrb_frame
*frame
;
2609 wpa_printf(MSG_DEBUG
, "FT: RRB authentication response: STA=" MACSTR
2610 " CurrentAP=" MACSTR
" status=%d",
2611 MAC2STR(sm
->addr
), MAC2STR(current_ap
), status
);
2612 wpa_hexdump(MSG_DEBUG
, "FT: Response IEs", resp_ies
, resp_ies_len
);
2614 /* RRB - Forward action frame response to the Current AP */
2617 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
2618 * Status_Code[2] FT Request action frame body[variable]
2620 rlen
= 2 + 2 * ETH_ALEN
+ 2 + resp_ies_len
;
2622 frame
= os_malloc(sizeof(*frame
) + rlen
);
2625 frame
->frame_type
= RSN_REMOTE_FRAME_TYPE_FT_RRB
;
2626 frame
->packet_type
= FT_PACKET_RESPONSE
;
2627 frame
->action_length
= host_to_le16(rlen
);
2628 os_memcpy(frame
->ap_address
, wpa_auth
->addr
, ETH_ALEN
);
2629 pos
= (u8
*) (frame
+ 1);
2630 *pos
++ = WLAN_ACTION_FT
;
2631 *pos
++ = 2; /* Action: Response */
2632 os_memcpy(pos
, sta_addr
, ETH_ALEN
);
2634 os_memcpy(pos
, wpa_auth
->addr
, ETH_ALEN
);
2636 WPA_PUT_LE16(pos
, status
);
2639 os_memcpy(pos
, resp_ies
, resp_ies_len
);
2641 wpa_ft_rrb_send(wpa_auth
, current_ap
, (u8
*) frame
,
2642 sizeof(*frame
) + rlen
);
2649 static int wpa_ft_rrb_build_r0(const u8
*key
, const size_t key_len
,
2650 const struct tlv_list
*tlvs
,
2651 const struct wpa_ft_pmk_r0_sa
*pmk_r0
,
2652 const u8
*r1kh_id
, const u8
*s1kh_id
,
2653 const struct tlv_list
*tlv_auth
,
2654 const u8
*src_addr
, u8 type
,
2655 u8
**packet
, size_t *packet_len
)
2658 u8 pmk_r1_name
[WPA_PMK_NAME_LEN
];
2659 u8 f_pairwise
[sizeof(le16
)];
2661 struct tlv_list sess_tlv
[] = {
2662 { .type
= FT_RRB_PMK_R1
, .len
= sizeof(pmk_r1
),
2664 { .type
= FT_RRB_PMK_R1_NAME
, .len
= sizeof(pmk_r1_name
),
2665 .data
= pmk_r1_name
},
2666 { .type
= FT_RRB_PAIRWISE
, .len
= sizeof(f_pairwise
),
2667 .data
= f_pairwise
},
2668 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
2672 return wpa_ft_rrb_build(key
, key_len
, tlvs
, NULL
, tlv_auth
,
2673 src_addr
, type
, packet
, packet_len
);
2675 if (wpa_derive_pmk_r1(pmk_r0
->pmk_r0
, pmk_r0
->pmk_r0_name
, r1kh_id
,
2676 s1kh_id
, pmk_r1
, pmk_r1_name
) < 0)
2678 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", pmk_r1
, PMK_LEN
);
2679 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name", pmk_r1_name
, WPA_PMK_NAME_LEN
);
2680 WPA_PUT_LE16(f_pairwise
, pmk_r0
->pairwise
);
2682 ret
= wpa_ft_rrb_build(key
, key_len
, tlvs
, sess_tlv
, tlv_auth
,
2683 src_addr
, type
, packet
, packet_len
);
2685 os_memset(pmk_r1
, 0, sizeof(pmk_r1
));
2691 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator
*wpa_auth
,
2693 const u8
*enc
, size_t enc_len
,
2694 const u8
*auth
, size_t auth_len
,
2697 const char *msgtype
= "pull request";
2698 u8
*plain
= NULL
, *packet
= NULL
;
2699 size_t plain_len
= 0, packet_len
= 0;
2700 struct ft_remote_r1kh
*r1kh
, *r1kh_wildcard
;
2704 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
, *f_s1kh_id
, *f_pmk_r0_name
;
2705 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
, f_s1kh_id_len
;
2706 size_t f_pmk_r0_name_len
;
2707 const struct wpa_ft_pmk_r0_sa
*r0
;
2709 struct tlv_list resp
[2];
2710 struct tlv_list resp_auth
[5];
2711 struct ft_rrb_seq f_seq
;
2713 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull");
2715 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
2716 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
2718 if (wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
)) {
2719 wpa_printf(MSG_DEBUG
, "FT: R0KH-ID mismatch");
2723 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
2724 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
2726 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
, &r1kh_wildcard
);
2729 key_len
= sizeof(r1kh
->key
);
2730 } else if (r1kh_wildcard
) {
2731 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R1KH-ID");
2732 key
= r1kh_wildcard
->key
;
2733 key_len
= sizeof(r1kh_wildcard
->key
);
2738 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "pull request", FT_RRB_NONCE_LEN
);
2739 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
2741 seq_ret
= FT_RRB_SEQ_DROP
;
2743 seq_ret
= wpa_ft_rrb_seq_chk(r1kh
->seq
, src_addr
, enc
, enc_len
,
2744 auth
, auth_len
, msgtype
, no_defer
);
2745 if (!no_defer
&& r1kh_wildcard
&&
2746 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
2747 /* wildcard: r1kh-id unknown or changed addr -> do a seq req */
2748 seq_ret
= FT_RRB_SEQ_DEFER
;
2751 if (seq_ret
== FT_RRB_SEQ_DROP
)
2754 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
2755 src_addr
, FT_PACKET_R0KH_R1KH_PULL
,
2756 &plain
, &plain_len
) < 0)
2760 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
, src_addr
,
2762 wpa_auth
->conf
.rkh_pos_timeout
);
2766 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
2767 wpa_ft_rrb_seq_req(wpa_auth
, r1kh
->seq
, src_addr
, f_r0kh_id
,
2768 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
2769 enc
, enc_len
, auth
, auth_len
,
2770 &wpa_ft_rrb_rx_pull
);
2774 wpa_ft_rrb_seq_accept(wpa_auth
, r1kh
->seq
, src_addr
, auth
, auth_len
,
2776 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
2777 wpa_auth
->conf
.rkh_pos_timeout
);
2779 RRB_GET(FT_RRB_PMK_R0_NAME
, pmk_r0_name
, msgtype
, WPA_PMK_NAME_LEN
);
2780 wpa_hexdump(MSG_DEBUG
, "FT: PMKR0Name", f_pmk_r0_name
,
2783 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
2784 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
2786 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
2787 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
2791 resp
[0].type
= FT_RRB_S1KH_ID
;
2792 resp
[0].len
= f_s1kh_id_len
;
2793 resp
[0].data
= f_s1kh_id
;
2794 resp
[1].type
= FT_RRB_LAST_EMPTY
;
2796 resp
[1].data
= NULL
;
2798 resp_auth
[0].type
= FT_RRB_NONCE
;
2799 resp_auth
[0].len
= f_nonce_len
;
2800 resp_auth
[0].data
= f_nonce
;
2801 resp_auth
[1].type
= FT_RRB_SEQ
;
2802 resp_auth
[1].len
= sizeof(f_seq
);
2803 resp_auth
[1].data
= (u8
*) &f_seq
;
2804 resp_auth
[2].type
= FT_RRB_R0KH_ID
;
2805 resp_auth
[2].len
= f_r0kh_id_len
;
2806 resp_auth
[2].data
= f_r0kh_id
;
2807 resp_auth
[3].type
= FT_RRB_R1KH_ID
;
2808 resp_auth
[3].len
= f_r1kh_id_len
;
2809 resp_auth
[3].data
= f_r1kh_id
;
2810 resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
2811 resp_auth
[4].len
= 0;
2812 resp_auth
[4].data
= NULL
;
2814 if (wpa_ft_fetch_pmk_r0(wpa_auth
, f_s1kh_id
, f_pmk_r0_name
, &r0
) < 0)
2815 wpa_printf(MSG_DEBUG
, "FT: No matching PMK-R0-Name found");
2817 ret
= wpa_ft_rrb_build_r0(key
, key_len
, resp
, r0
, f_r1kh_id
, f_s1kh_id
,
2818 resp_auth
, wpa_auth
->addr
,
2819 FT_PACKET_R0KH_R1KH_RESP
,
2820 &packet
, &packet_len
);
2823 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
2824 FT_PACKET_R0KH_R1KH_RESP
, packet
,
2835 /* @returns 0 on success
2837 * -2 if FR_RRB_PAIRWISE is missing
2839 static int wpa_ft_rrb_rx_r1(struct wpa_authenticator
*wpa_auth
,
2840 const u8
*src_addr
, u8 type
,
2841 const u8
*enc
, size_t enc_len
,
2842 const u8
*auth
, size_t auth_len
,
2843 const char *msgtype
, u8
*s1kh_id_out
,
2844 int (*cb
)(struct wpa_authenticator
*wpa_auth
,
2846 const u8
*enc
, size_t enc_len
,
2847 const u8
*auth
, size_t auth_len
,
2851 size_t plain_len
= 0;
2852 struct ft_remote_r0kh
*r0kh
, *r0kh_wildcard
;
2856 const u8
*f_r1kh_id
, *f_s1kh_id
, *f_r0kh_id
;
2857 const u8
*f_pmk_r1_name
, *f_pairwise
, *f_pmk_r1
;
2858 size_t f_r1kh_id_len
, f_s1kh_id_len
, f_r0kh_id_len
;
2859 size_t f_pmk_r1_name_len
, f_pairwise_len
, f_pmk_r1_len
;
2863 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, msgtype
, -1);
2864 wpa_hexdump(MSG_DEBUG
, "FT: R0KH-ID", f_r0kh_id
, f_r0kh_id_len
);
2866 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, msgtype
, FT_R1KH_ID_LEN
);
2867 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID=" MACSTR
, MAC2STR(f_r1kh_id
));
2869 if (wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
)) {
2870 wpa_printf(MSG_DEBUG
, "FT: R1KH-ID mismatch");
2874 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
, &r0kh
,
2878 key_len
= sizeof(r0kh
->key
);
2879 } else if (r0kh_wildcard
) {
2880 wpa_printf(MSG_DEBUG
, "FT: Using wildcard R0KH-ID");
2881 key
= r0kh_wildcard
->key
;
2882 key_len
= sizeof(r0kh_wildcard
->key
);
2887 seq_ret
= FT_RRB_SEQ_DROP
;
2889 seq_ret
= wpa_ft_rrb_seq_chk(r0kh
->seq
, src_addr
, enc
, enc_len
,
2890 auth
, auth_len
, msgtype
,
2893 if (cb
&& r0kh_wildcard
&&
2894 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
2895 /* wildcard: r0kh-id unknown or changed addr -> do a seq req */
2896 seq_ret
= FT_RRB_SEQ_DEFER
;
2899 if (seq_ret
== FT_RRB_SEQ_DROP
)
2902 if (wpa_ft_rrb_decrypt(key
, key_len
, enc
, enc_len
, auth
, auth_len
,
2903 src_addr
, type
, &plain
, &plain_len
) < 0)
2907 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
, src_addr
,
2908 f_r0kh_id
, f_r0kh_id_len
,
2909 wpa_auth
->conf
.rkh_pos_timeout
);
2913 if (seq_ret
== FT_RRB_SEQ_DEFER
) {
2914 wpa_ft_rrb_seq_req(wpa_auth
, r0kh
->seq
, src_addr
, f_r0kh_id
,
2915 f_r0kh_id_len
, f_r1kh_id
, key
, key_len
,
2916 enc
, enc_len
, auth
, auth_len
, cb
);
2920 wpa_ft_rrb_seq_accept(wpa_auth
, r0kh
->seq
, src_addr
, auth
, auth_len
,
2922 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
2923 wpa_auth
->conf
.rkh_pos_timeout
);
2925 RRB_GET(FT_RRB_S1KH_ID
, s1kh_id
, msgtype
, ETH_ALEN
);
2926 wpa_printf(MSG_DEBUG
, "FT: S1KH-ID=" MACSTR
, MAC2STR(f_s1kh_id
));
2929 os_memcpy(s1kh_id_out
, f_s1kh_id
, ETH_ALEN
);
2932 RRB_GET(FT_RRB_PAIRWISE
, pairwise
, msgtype
, sizeof(le16
));
2933 wpa_hexdump(MSG_DEBUG
, "FT: pairwise", f_pairwise
, f_pairwise_len
);
2936 RRB_GET(FT_RRB_PMK_R1_NAME
, pmk_r1_name
, msgtype
, WPA_PMK_NAME_LEN
);
2937 wpa_hexdump(MSG_DEBUG
, "FT: PMKR1Name",
2938 f_pmk_r1_name
, WPA_PMK_NAME_LEN
);
2940 RRB_GET(FT_RRB_PMK_R1
, pmk_r1
, msgtype
, PMK_LEN
);
2941 wpa_hexdump_key(MSG_DEBUG
, "FT: PMK-R1", f_pmk_r1
, PMK_LEN
);
2943 pairwise
= WPA_GET_LE16(f_pairwise
);
2945 if (wpa_ft_store_pmk_r1(wpa_auth
, f_s1kh_id
, f_pmk_r1
, f_pmk_r1_name
,
2952 os_memset(plain
, 0, plain_len
);
2961 static void ft_finish_pull(struct wpa_state_machine
*sm
)
2965 size_t resp_ies_len
;
2968 if (!sm
->ft_pending_cb
|| !sm
->ft_pending_req_ies
)
2971 res
= wpa_ft_process_auth_req(sm
, wpabuf_head(sm
->ft_pending_req_ies
),
2972 wpabuf_len(sm
->ft_pending_req_ies
),
2973 &resp_ies
, &resp_ies_len
);
2975 /* this loop is broken by ft_pending_pull_left_retries */
2976 wpa_printf(MSG_DEBUG
,
2977 "FT: Callback postponed until response is available");
2980 wpabuf_free(sm
->ft_pending_req_ies
);
2981 sm
->ft_pending_req_ies
= NULL
;
2983 wpa_printf(MSG_DEBUG
, "FT: Postponed auth callback result for " MACSTR
2984 " - status %u", MAC2STR(sm
->addr
), status
);
2986 sm
->ft_pending_cb(sm
->ft_pending_cb_ctx
, sm
->addr
, sm
->wpa_auth
->addr
,
2987 sm
->ft_pending_auth_transaction
+ 1, status
,
2988 resp_ies
, resp_ies_len
);
2993 struct ft_get_sta_ctx
{
2996 struct wpa_state_machine
*sm
;
3000 static int ft_get_sta_cb(struct wpa_state_machine
*sm
, void *ctx
)
3002 struct ft_get_sta_ctx
*info
= ctx
;
3004 if ((info
->s1kh_id
&&
3005 os_memcmp(info
->s1kh_id
, sm
->addr
, ETH_ALEN
) != 0) ||
3006 os_memcmp(info
->nonce
, sm
->ft_pending_pull_nonce
,
3007 FT_RRB_NONCE_LEN
) != 0 ||
3008 sm
->ft_pending_cb
== NULL
|| sm
->ft_pending_req_ies
== NULL
)
3017 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator
*wpa_auth
,
3019 const u8
*enc
, size_t enc_len
,
3020 const u8
*auth
, size_t auth_len
,
3023 const char *msgtype
= "pull response";
3025 struct ft_get_sta_ctx ctx
;
3026 u8 s1kh_id
[ETH_ALEN
];
3030 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 pull response");
3032 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, msgtype
, FT_RRB_NONCE_LEN
);
3033 wpa_hexdump(MSG_DEBUG
, "FT: nonce", f_nonce
, f_nonce_len
);
3035 os_memset(&ctx
, 0, sizeof(ctx
));
3036 ctx
.nonce
= f_nonce
;
3037 if (!wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3038 /* nonce not found */
3039 wpa_printf(MSG_DEBUG
, "FT: Invalid nonce");
3043 ret
= wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_RESP
,
3044 enc
, enc_len
, auth
, auth_len
, msgtype
, s1kh_id
,
3045 no_defer
? NULL
: &wpa_ft_rrb_rx_resp
);
3055 ctx
.s1kh_id
= s1kh_id
;
3056 if (wpa_auth_for_each_sta(wpa_auth
, ft_get_sta_cb
, &ctx
)) {
3057 wpa_printf(MSG_DEBUG
,
3058 "FT: Response to a pending pull request for " MACSTR
,
3059 MAC2STR(ctx
.sm
->addr
));
3060 eloop_cancel_timeout(wpa_ft_expire_pull
, ctx
.sm
, NULL
);
3062 ctx
.sm
->ft_pending_pull_left_retries
= 0;
3063 ft_finish_pull(ctx
.sm
);
3071 static int wpa_ft_rrb_rx_push(struct wpa_authenticator
*wpa_auth
,
3073 const u8
*enc
, size_t enc_len
,
3074 const u8
*auth
, size_t auth_len
, int no_defer
)
3076 const char *msgtype
= "push";
3078 wpa_printf(MSG_DEBUG
, "FT: Received PMK-R1 push");
3080 if (wpa_ft_rrb_rx_r1(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3081 enc
, enc_len
, auth
, auth_len
, msgtype
, NULL
,
3082 no_defer
? NULL
: wpa_ft_rrb_rx_push
) < 0)
3089 static int wpa_ft_rrb_rx_seq(struct wpa_authenticator
*wpa_auth
,
3090 const u8
*src_addr
, int type
,
3091 const u8
*enc
, size_t enc_len
,
3092 const u8
*auth
, size_t auth_len
,
3093 struct ft_remote_seq
**rkh_seq
,
3094 u8
**key
, size_t *key_len
,
3095 struct ft_remote_r0kh
**r0kh_out
,
3096 struct ft_remote_r1kh
**r1kh_out
,
3097 struct ft_remote_r0kh
**r0kh_wildcard_out
,
3098 struct ft_remote_r1kh
**r1kh_wildcard_out
)
3100 struct ft_remote_r0kh
*r0kh
= NULL
;
3101 struct ft_remote_r1kh
*r1kh
= NULL
;
3102 const u8
*f_r0kh_id
, *f_r1kh_id
;
3103 size_t f_r0kh_id_len
, f_r1kh_id_len
;
3104 int to_r0kh
, to_r1kh
;
3106 size_t plain_len
= 0;
3107 struct ft_remote_r0kh
*r0kh_wildcard
;
3108 struct ft_remote_r1kh
*r1kh_wildcard
;
3110 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3111 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3113 to_r0kh
= !wpa_ft_rrb_check_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
);
3114 to_r1kh
= !wpa_ft_rrb_check_r1kh(wpa_auth
, f_r1kh_id
);
3116 if (to_r0kh
&& to_r1kh
) {
3117 wpa_printf(MSG_DEBUG
, "FT: seq - local R0KH-ID and R1KH-ID");
3121 if (!to_r0kh
&& !to_r1kh
) {
3122 wpa_printf(MSG_DEBUG
, "FT: seq - remote R0KH-ID and R1KH-ID");
3127 wpa_ft_rrb_lookup_r0kh(wpa_auth
, f_r0kh_id
, f_r0kh_id_len
,
3128 &r0kh
, &r0kh_wildcard
);
3129 if (!r0kh_wildcard
&&
3130 (!r0kh
|| os_memcmp(r0kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3131 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R0KH-ID",
3132 f_r0kh_id
, f_r0kh_id_len
);
3137 *key_len
= sizeof(r0kh
->key
);
3139 *key
= r0kh_wildcard
->key
;
3140 *key_len
= sizeof(r0kh_wildcard
->key
);
3145 wpa_ft_rrb_lookup_r1kh(wpa_auth
, f_r1kh_id
, &r1kh
,
3147 if (!r1kh_wildcard
&&
3148 (!r1kh
|| os_memcmp(r1kh
->addr
, src_addr
, ETH_ALEN
) != 0)) {
3149 wpa_hexdump(MSG_DEBUG
, "FT: Did not find R1KH-ID",
3150 f_r1kh_id
, FT_R1KH_ID_LEN
);
3155 *key_len
= sizeof(r1kh
->key
);
3157 *key
= r1kh_wildcard
->key
;
3158 *key_len
= sizeof(r1kh_wildcard
->key
);
3162 if (wpa_ft_rrb_decrypt(*key
, *key_len
, enc
, enc_len
, auth
, auth_len
,
3163 src_addr
, type
, &plain
, &plain_len
) < 0)
3170 r0kh
= wpa_ft_rrb_add_r0kh(wpa_auth
, r0kh_wildcard
,
3171 src_addr
, f_r0kh_id
,
3177 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
, ftRRBseqTimeout
);
3178 *rkh_seq
= r0kh
->seq
;
3181 if (r0kh_wildcard_out
)
3182 *r0kh_wildcard_out
= r0kh_wildcard
;
3187 r1kh
= wpa_ft_rrb_add_r1kh(wpa_auth
, r1kh_wildcard
,
3188 src_addr
, f_r1kh_id
,
3193 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
, ftRRBseqTimeout
);
3194 *rkh_seq
= r1kh
->seq
;
3197 if (r1kh_wildcard_out
)
3198 *r1kh_wildcard_out
= r1kh_wildcard
;
3207 static int wpa_ft_rrb_rx_seq_req(struct wpa_authenticator
*wpa_auth
,
3209 const u8
*enc
, size_t enc_len
,
3210 const u8
*auth
, size_t auth_len
,
3214 struct ft_rrb_seq f_seq
;
3215 const u8
*f_nonce
, *f_r0kh_id
, *f_r1kh_id
;
3216 size_t f_nonce_len
, f_r0kh_id_len
, f_r1kh_id_len
;
3217 struct ft_remote_seq
*rkh_seq
= NULL
;
3218 u8
*packet
= NULL
, *key
= NULL
;
3219 size_t packet_len
= 0, key_len
= 0;
3220 struct tlv_list seq_resp_auth
[5];
3222 wpa_printf(MSG_DEBUG
, "FT: Received sequence number request");
3224 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_REQ
,
3225 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3226 &key_len
, NULL
, NULL
, NULL
, NULL
) < 0)
3229 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq request", FT_RRB_NONCE_LEN
);
3230 wpa_hexdump(MSG_DEBUG
, "FT: seq request - nonce", f_nonce
, f_nonce_len
);
3232 RRB_GET_AUTH(FT_RRB_R0KH_ID
, r0kh_id
, "seq", -1);
3233 RRB_GET_AUTH(FT_RRB_R1KH_ID
, r1kh_id
, "seq", FT_R1KH_ID_LEN
);
3235 if (wpa_ft_new_seq(rkh_seq
, &f_seq
) < 0) {
3236 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3240 seq_resp_auth
[0].type
= FT_RRB_NONCE
;
3241 seq_resp_auth
[0].len
= f_nonce_len
;
3242 seq_resp_auth
[0].data
= f_nonce
;
3243 seq_resp_auth
[1].type
= FT_RRB_SEQ
;
3244 seq_resp_auth
[1].len
= sizeof(f_seq
);
3245 seq_resp_auth
[1].data
= (u8
*) &f_seq
;
3246 seq_resp_auth
[2].type
= FT_RRB_R0KH_ID
;
3247 seq_resp_auth
[2].len
= f_r0kh_id_len
;
3248 seq_resp_auth
[2].data
= f_r0kh_id
;
3249 seq_resp_auth
[3].type
= FT_RRB_R1KH_ID
;
3250 seq_resp_auth
[3].len
= FT_R1KH_ID_LEN
;
3251 seq_resp_auth
[3].data
= f_r1kh_id
;
3252 seq_resp_auth
[4].type
= FT_RRB_LAST_EMPTY
;
3253 seq_resp_auth
[4].len
= 0;
3254 seq_resp_auth
[4].data
= NULL
;
3256 if (wpa_ft_rrb_build(key
, key_len
, NULL
, NULL
, seq_resp_auth
,
3257 wpa_auth
->addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3258 &packet
, &packet_len
) < 0)
3261 wpa_ft_rrb_oui_send(wpa_auth
, src_addr
,
3262 FT_PACKET_R0KH_R1KH_SEQ_RESP
, packet
,
3272 static int wpa_ft_rrb_rx_seq_resp(struct wpa_authenticator
*wpa_auth
,
3274 const u8
*enc
, size_t enc_len
,
3275 const u8
*auth
, size_t auth_len
,
3280 struct ft_remote_r0kh
*r0kh
= NULL
, *r0kh_wildcard
= NULL
;
3281 struct ft_remote_r1kh
*r1kh
= NULL
, *r1kh_wildcard
= NULL
;
3282 const u8
*f_nonce
, *f_seq
;
3283 size_t f_nonce_len
, f_seq_len
;
3284 struct ft_remote_seq
*rkh_seq
= NULL
;
3285 struct ft_remote_item
*item
;
3286 struct os_reltime now
, now_remote
;
3288 const struct ft_rrb_seq
*msg_both
;
3289 u32 msg_dom
, msg_seq
;
3291 wpa_printf(MSG_DEBUG
, "FT: Received sequence number response");
3293 if (wpa_ft_rrb_rx_seq(wpa_auth
, src_addr
, FT_PACKET_R0KH_R1KH_SEQ_RESP
,
3294 enc
, enc_len
, auth
, auth_len
, &rkh_seq
, &key
,
3295 &key_len
, &r0kh
, &r1kh
, &r0kh_wildcard
,
3296 &r1kh_wildcard
) < 0)
3299 RRB_GET_AUTH(FT_RRB_NONCE
, nonce
, "seq response", FT_RRB_NONCE_LEN
);
3300 wpa_hexdump(MSG_DEBUG
, "FT: seq response - nonce", f_nonce
,
3304 dl_list_for_each(item
, &rkh_seq
->rx
.queue
, struct ft_remote_item
,
3306 if (os_memcmp_const(f_nonce
, item
->nonce
,
3307 FT_RRB_NONCE_LEN
) != 0 ||
3308 os_get_reltime(&now
) < 0 ||
3309 os_reltime_expired(&now
, &item
->nonce_ts
, ftRRBseqTimeout
))
3316 wpa_printf(MSG_DEBUG
, "FT: seq response - bad nonce");
3321 wpa_ft_rrb_r0kh_replenish(wpa_auth
, r0kh
,
3322 wpa_auth
->conf
.rkh_pos_timeout
);
3324 os_memcpy(r0kh
->addr
, src_addr
, ETH_ALEN
);
3328 wpa_ft_rrb_r1kh_replenish(wpa_auth
, r1kh
,
3329 wpa_auth
->conf
.rkh_pos_timeout
);
3331 os_memcpy(r1kh
->addr
, src_addr
, ETH_ALEN
);
3334 seq_ret
= wpa_ft_rrb_seq_chk(rkh_seq
, src_addr
, enc
, enc_len
, auth
,
3335 auth_len
, "seq response", 1);
3336 if (seq_ret
== FT_RRB_SEQ_OK
) {
3337 wpa_printf(MSG_DEBUG
, "FT: seq response - valid seq number");
3338 wpa_ft_rrb_seq_accept(wpa_auth
, rkh_seq
, src_addr
, auth
,
3339 auth_len
, "seq response");
3341 wpa_printf(MSG_DEBUG
, "FT: seq response - reset seq number");
3343 RRB_GET_AUTH(FT_RRB_SEQ
, seq
, "seq response",
3345 msg_both
= (const struct ft_rrb_seq
*) f_seq
;
3347 msg_dom
= le_to_host32(msg_both
->dom
);
3348 msg_seq
= le_to_host32(msg_both
->seq
);
3349 now_remote
.sec
= le_to_host32(msg_both
->ts
);
3350 now_remote
.usec
= 0;
3352 rkh_seq
->rx
.num_last
= 2;
3353 rkh_seq
->rx
.dom
= msg_dom
;
3354 rkh_seq
->rx
.offsetidx
= 0;
3355 /* Accept some older, possibly cached packets as well */
3356 rkh_seq
->rx
.last
[0] = msg_seq
- FT_REMOTE_SEQ_BACKLOG
-
3357 dl_list_len(&rkh_seq
->rx
.queue
);
3358 rkh_seq
->rx
.last
[1] = msg_seq
;
3360 /* local time - offset = remote time
3361 * <=> local time - remote time = offset */
3362 os_reltime_sub(&now
, &now_remote
, &rkh_seq
->rx
.time_offset
);
3365 wpa_ft_rrb_seq_flush(wpa_auth
, rkh_seq
, 1);
3373 int wpa_ft_rrb_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
3374 const u8
*data
, size_t data_len
)
3376 struct ft_rrb_frame
*frame
;
3378 const u8
*pos
, *end
, *start
;
3380 const u8
*sta_addr
, *target_ap_addr
;
3382 wpa_printf(MSG_DEBUG
, "FT: RRB received frame from remote AP " MACSTR
,
3385 if (data_len
< sizeof(*frame
)) {
3386 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (data_len=%lu)",
3387 (unsigned long) data_len
);
3392 frame
= (struct ft_rrb_frame
*) pos
;
3393 pos
+= sizeof(*frame
);
3395 alen
= le_to_host16(frame
->action_length
);
3396 wpa_printf(MSG_DEBUG
, "FT: RRB frame - frame_type=%d packet_type=%d "
3397 "action_length=%d ap_address=" MACSTR
,
3398 frame
->frame_type
, frame
->packet_type
, alen
,
3399 MAC2STR(frame
->ap_address
));
3401 if (frame
->frame_type
!= RSN_REMOTE_FRAME_TYPE_FT_RRB
) {
3402 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
3403 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with "
3404 "unrecognized type %d", frame
->frame_type
);
3408 if (alen
> data_len
- sizeof(*frame
)) {
3409 wpa_printf(MSG_DEBUG
, "FT: RRB frame too short for action "
3414 wpa_hexdump(MSG_MSGDUMP
, "FT: RRB - FT Action frame", pos
, alen
);
3416 if (alen
< 1 + 1 + 2 * ETH_ALEN
) {
3417 wpa_printf(MSG_DEBUG
, "FT: Too short RRB frame (not enough "
3418 "room for Action Frame body); alen=%lu",
3419 (unsigned long) alen
);
3425 if (*pos
!= WLAN_ACTION_FT
) {
3426 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action frame category "
3435 target_ap_addr
= pos
;
3437 wpa_printf(MSG_DEBUG
, "FT: RRB Action Frame: action=%d sta_addr="
3438 MACSTR
" target_ap_addr=" MACSTR
,
3439 action
, MAC2STR(sta_addr
), MAC2STR(target_ap_addr
));
3441 if (frame
->packet_type
== FT_PACKET_REQUEST
) {
3442 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Request");
3445 wpa_printf(MSG_DEBUG
, "FT: Unexpected Action %d in "
3446 "RRB Request", action
);
3450 if (os_memcmp(target_ap_addr
, wpa_auth
->addr
, ETH_ALEN
) != 0) {
3451 wpa_printf(MSG_DEBUG
, "FT: Target AP address in the "
3452 "RRB Request does not match with own "
3457 if (wpa_ft_rrb_rx_request(wpa_auth
, frame
->ap_address
,
3458 sta_addr
, pos
, end
- pos
) < 0)
3460 } else if (frame
->packet_type
== FT_PACKET_RESPONSE
) {
3463 if (end
- pos
< 2) {
3464 wpa_printf(MSG_DEBUG
, "FT: Not enough room for status "
3465 "code in RRB Response");
3468 status_code
= WPA_GET_LE16(pos
);
3471 wpa_printf(MSG_DEBUG
, "FT: FT Packet Type - Response "
3472 "(status_code=%d)", status_code
);
3474 if (wpa_ft_action_send(wpa_auth
, sta_addr
, start
, alen
) < 0)
3477 wpa_printf(MSG_DEBUG
, "FT: RRB discarded frame with unknown "
3478 "packet_type %d", frame
->packet_type
);
3483 wpa_hexdump(MSG_DEBUG
, "FT: Ignore extra data in end",
3491 void wpa_ft_rrb_oui_rx(struct wpa_authenticator
*wpa_auth
, const u8
*src_addr
,
3492 const u8
*dst_addr
, u8 oui_suffix
, const u8
*data
,
3495 const u8
*auth
, *enc
;
3499 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI received frame from remote AP "
3500 MACSTR
, MAC2STR(src_addr
));
3501 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame - oui_suffix=%d", oui_suffix
);
3503 if (is_multicast_ether_addr(src_addr
)) {
3504 wpa_printf(MSG_DEBUG
,
3505 "FT: RRB-OUI received frame from multicast address "
3506 MACSTR
, MAC2STR(src_addr
));
3510 if (is_multicast_ether_addr(dst_addr
)) {
3511 wpa_printf(MSG_DEBUG
,
3512 "FT: RRB-OUI received frame from remote AP " MACSTR
3513 " to multicast address " MACSTR
,
3514 MAC2STR(src_addr
), MAC2STR(dst_addr
));
3518 if (data_len
< sizeof(u16
)) {
3519 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
3523 alen
= WPA_GET_LE16(data
);
3524 if (data_len
< sizeof(u16
) + alen
) {
3525 wpa_printf(MSG_DEBUG
, "FT: RRB-OUI frame too short");
3529 auth
= data
+ sizeof(u16
);
3530 enc
= data
+ sizeof(u16
) + alen
;
3531 elen
= data_len
- sizeof(u16
) - alen
;
3533 switch (oui_suffix
) {
3534 case FT_PACKET_R0KH_R1KH_PULL
:
3535 wpa_ft_rrb_rx_pull(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3538 case FT_PACKET_R0KH_R1KH_RESP
:
3539 wpa_ft_rrb_rx_resp(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3542 case FT_PACKET_R0KH_R1KH_PUSH
:
3543 wpa_ft_rrb_rx_push(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3546 case FT_PACKET_R0KH_R1KH_SEQ_REQ
:
3547 wpa_ft_rrb_rx_seq_req(wpa_auth
, src_addr
, enc
, elen
, auth
, alen
,
3550 case FT_PACKET_R0KH_R1KH_SEQ_RESP
:
3551 wpa_ft_rrb_rx_seq_resp(wpa_auth
, src_addr
, enc
, elen
, auth
,
3558 static int wpa_ft_generate_pmk_r1(struct wpa_authenticator
*wpa_auth
,
3559 struct wpa_ft_pmk_r0_sa
*pmk_r0
,
3560 struct ft_remote_r1kh
*r1kh
,
3565 struct ft_rrb_seq f_seq
;
3566 struct tlv_list push
[] = {
3567 { .type
= FT_RRB_S1KH_ID
, .len
= ETH_ALEN
,
3569 { .type
= FT_RRB_PMK_R0_NAME
, .len
= WPA_PMK_NAME_LEN
,
3570 .data
= pmk_r0
->pmk_r0_name
},
3571 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3573 struct tlv_list push_auth
[] = {
3574 { .type
= FT_RRB_SEQ
, .len
= sizeof(f_seq
),
3575 .data
= (u8
*) &f_seq
},
3576 { .type
= FT_RRB_R0KH_ID
,
3577 .len
= wpa_auth
->conf
.r0_key_holder_len
,
3578 .data
= wpa_auth
->conf
.r0_key_holder
},
3579 { .type
= FT_RRB_R1KH_ID
, .len
= FT_R1KH_ID_LEN
,
3581 { .type
= FT_RRB_LAST_EMPTY
, .len
= 0, .data
= NULL
},
3584 if (wpa_ft_new_seq(r1kh
->seq
, &f_seq
) < 0) {
3585 wpa_printf(MSG_DEBUG
, "FT: Failed to get seq num");
3589 if (wpa_ft_rrb_build_r0(r1kh
->key
, sizeof(r1kh
->key
), push
, pmk_r0
,
3590 r1kh
->id
, s1kh_id
, push_auth
, wpa_auth
->addr
,
3591 FT_PACKET_R0KH_R1KH_PUSH
,
3592 &packet
, &packet_len
) < 0)
3595 wpa_ft_rrb_oui_send(wpa_auth
, r1kh
->addr
, FT_PACKET_R0KH_R1KH_PUSH
,
3596 packet
, packet_len
);
3603 void wpa_ft_push_pmk_r1(struct wpa_authenticator
*wpa_auth
, const u8
*addr
)
3605 struct wpa_ft_pmk_r0_sa
*r0
;
3606 struct ft_remote_r1kh
*r1kh
;
3608 if (!wpa_auth
->conf
.pmk_r1_push
)
3610 if (!wpa_auth
->conf
.r1kh_list
)
3613 r0
= wpa_auth
->ft_pmk_cache
->pmk_r0
;
3615 if (os_memcmp(r0
->spa
, addr
, ETH_ALEN
) == 0)
3620 if (r0
== NULL
|| r0
->pmk_r1_pushed
)
3622 r0
->pmk_r1_pushed
= 1;
3624 wpa_printf(MSG_DEBUG
, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
3625 "for STA " MACSTR
, MAC2STR(addr
));
3627 for (r1kh
= *wpa_auth
->conf
.r1kh_list
; r1kh
; r1kh
= r1kh
->next
) {
3628 if (is_zero_ether_addr(r1kh
->addr
) ||
3629 is_zero_ether_addr(r1kh
->id
))
3631 if (wpa_ft_rrb_init_r1kh_seq(r1kh
) < 0)
3633 wpa_ft_generate_pmk_r1(wpa_auth
, r0
, r1kh
, addr
);
3637 #endif /* CONFIG_IEEE80211R_AP */