2 * WPA Supplicant - Mesh RSN routines
3 * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved.
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 "crypto/sha256.h"
14 #include "crypto/random.h"
15 #include "crypto/aes.h"
16 #include "crypto/aes_siv.h"
17 #include "rsn_supp/wpa.h"
18 #include "ap/hostapd.h"
19 #include "ap/wpa_auth.h"
20 #include "ap/sta_info.h"
21 #include "ap/ieee802_11.h"
22 #include "wpa_supplicant_i.h"
24 #include "wpas_glue.h"
28 #define MESH_AUTH_TIMEOUT 10
29 #define MESH_AUTH_RETRY 3
31 void mesh_auth_timer(void *eloop_ctx
, void *user_data
)
33 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
34 struct sta_info
*sta
= user_data
;
35 struct hostapd_data
*hapd
;
37 if (sta
->sae
->state
!= SAE_ACCEPTED
) {
38 wpa_printf(MSG_DEBUG
, "AUTH: Re-authenticate with " MACSTR
40 MAC2STR(sta
->addr
), sta
->sae_auth_retry
);
41 wpa_msg(wpa_s
, MSG_INFO
, MESH_SAE_AUTH_FAILURE
"addr=" MACSTR
,
43 if (sta
->sae_auth_retry
< MESH_AUTH_RETRY
) {
44 mesh_rsn_auth_sae_sta(wpa_s
, sta
);
46 hapd
= wpa_s
->ifmsh
->bss
[0];
48 if (sta
->sae_auth_retry
> MESH_AUTH_RETRY
) {
49 ap_free_sta(hapd
, sta
);
53 /* block the STA if exceeded the number of attempts */
54 wpa_mesh_set_plink_state(wpa_s
, sta
, PLINK_BLOCKED
);
55 sta
->sae
->state
= SAE_NOTHING
;
56 wpa_msg(wpa_s
, MSG_INFO
, MESH_SAE_AUTH_BLOCKED
"addr="
57 MACSTR
" duration=%d",
59 hapd
->conf
->ap_max_inactivity
);
61 sta
->sae_auth_retry
++;
66 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
70 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
73 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
77 static const u8
*auth_get_psk(void *ctx
, const u8
*addr
,
78 const u8
*p2p_dev_addr
, const u8
*prev_psk
,
79 size_t *psk_len
, int *vlan_id
)
81 struct mesh_rsn
*mesh_rsn
= ctx
;
82 struct hostapd_data
*hapd
= mesh_rsn
->wpa_s
->ifmsh
->bss
[0];
83 struct sta_info
*sta
= ap_get_sta(hapd
, addr
);
89 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
90 __func__
, MAC2STR(addr
), prev_psk
);
92 if (sta
&& sta
->auth_alg
== WLAN_AUTH_SAE
) {
93 if (!sta
->sae
|| prev_psk
)
102 static int auth_set_key(void *ctx
, int vlan_id
, enum wpa_alg alg
,
103 const u8
*addr
, int idx
, u8
*key
, size_t key_len
,
104 enum key_flag key_flag
)
106 struct mesh_rsn
*mesh_rsn
= ctx
;
109 os_memset(seq
, 0, sizeof(seq
));
112 wpa_printf(MSG_DEBUG
, "AUTH: %s(alg=%d addr=" MACSTR
114 __func__
, alg
, MAC2STR(addr
), idx
);
116 wpa_printf(MSG_DEBUG
, "AUTH: %s(alg=%d key_idx=%d)",
119 wpa_hexdump_key(MSG_DEBUG
, "AUTH: set_key - key", key
, key_len
);
121 return wpa_drv_set_key(mesh_rsn
->wpa_s
, alg
, addr
, idx
,
122 1, seq
, 6, key
, key_len
, key_flag
);
126 static int auth_start_ampe(void *ctx
, const u8
*addr
)
128 struct mesh_rsn
*mesh_rsn
= ctx
;
129 struct hostapd_data
*hapd
;
130 struct sta_info
*sta
;
132 if (mesh_rsn
->wpa_s
->current_ssid
->mode
!= WPAS_MODE_MESH
)
135 hapd
= mesh_rsn
->wpa_s
->ifmsh
->bss
[0];
136 sta
= ap_get_sta(hapd
, addr
);
138 eloop_cancel_timeout(mesh_auth_timer
, mesh_rsn
->wpa_s
, sta
);
140 mesh_mpm_auth_peer(mesh_rsn
->wpa_s
, addr
);
145 static int __mesh_rsn_auth_init(struct mesh_rsn
*rsn
, const u8
*addr
,
146 enum mfp_options ieee80211w
, int ocv
)
148 struct wpa_auth_config conf
;
149 static const struct wpa_auth_callbacks cb
= {
150 .logger
= auth_logger
,
151 .get_psk
= auth_get_psk
,
152 .set_key
= auth_set_key
,
153 .start_ampe
= auth_start_ampe
,
157 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
159 os_memset(&conf
, 0, sizeof(conf
));
160 conf
.wpa
= WPA_PROTO_RSN
;
161 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_SAE
;
162 conf
.wpa_pairwise
= rsn
->pairwise_cipher
;
163 conf
.rsn_pairwise
= rsn
->pairwise_cipher
;
164 conf
.wpa_group
= rsn
->group_cipher
;
165 conf
.eapol_version
= 0;
166 conf
.wpa_group_rekey
= -1;
167 conf
.wpa_group_update_count
= 4;
168 conf
.wpa_pairwise_update_count
= 4;
169 conf
.ieee80211w
= ieee80211w
;
170 if (ieee80211w
!= NO_MGMT_FRAME_PROTECTION
)
171 conf
.group_mgmt_cipher
= rsn
->mgmt_group_cipher
;
174 #endif /* CONFIG_OCV */
176 rsn
->auth
= wpa_init(addr
, &conf
, &cb
, rsn
);
177 if (rsn
->auth
== NULL
) {
178 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
182 /* TODO: support rekeying */
183 rsn
->mgtk_len
= wpa_cipher_key_len(conf
.wpa_group
);
184 if (random_get_bytes(rsn
->mgtk
, rsn
->mgtk_len
) < 0)
186 rsn
->mgtk_key_id
= 1;
188 if (ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
189 rsn
->igtk_len
= wpa_cipher_key_len(conf
.group_mgmt_cipher
);
190 if (random_get_bytes(rsn
->igtk
, rsn
->igtk_len
) < 0)
192 rsn
->igtk_key_id
= 4;
195 wpa_hexdump_key(MSG_DEBUG
, "mesh: Own TX IGTK",
196 rsn
->igtk
, rsn
->igtk_len
);
197 wpa_drv_set_key(rsn
->wpa_s
,
198 wpa_cipher_to_alg(rsn
->mgmt_group_cipher
), NULL
,
200 seq
, sizeof(seq
), rsn
->igtk
, rsn
->igtk_len
,
201 KEY_FLAG_GROUP_TX_DEFAULT
);
204 /* group privacy / data frames */
205 wpa_hexdump_key(MSG_DEBUG
, "mesh: Own TX MGTK",
206 rsn
->mgtk
, rsn
->mgtk_len
);
207 wpa_drv_set_key(rsn
->wpa_s
, wpa_cipher_to_alg(rsn
->group_cipher
), NULL
,
208 rsn
->mgtk_key_id
, 1, seq
, sizeof(seq
),
209 rsn
->mgtk
, rsn
->mgtk_len
, KEY_FLAG_GROUP_TX_DEFAULT
);
215 static void mesh_rsn_deinit(struct mesh_rsn
*rsn
)
217 os_memset(rsn
->mgtk
, 0, sizeof(rsn
->mgtk
));
219 os_memset(rsn
->igtk
, 0, sizeof(rsn
->igtk
));
222 wpa_deinit(rsn
->auth
);
226 struct mesh_rsn
*mesh_rsn_auth_init(struct wpa_supplicant
*wpa_s
,
227 struct mesh_conf
*conf
)
229 struct mesh_rsn
*mesh_rsn
;
230 struct hostapd_data
*bss
= wpa_s
->ifmsh
->bss
[0];
233 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
234 struct external_pmksa_cache
*entry
;
235 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
237 mesh_rsn
= os_zalloc(sizeof(*mesh_rsn
));
238 if (mesh_rsn
== NULL
)
240 mesh_rsn
->wpa_s
= wpa_s
;
241 mesh_rsn
->pairwise_cipher
= conf
->pairwise_cipher
;
242 mesh_rsn
->group_cipher
= conf
->group_cipher
;
243 mesh_rsn
->mgmt_group_cipher
= conf
->mgmt_group_cipher
;
245 if (__mesh_rsn_auth_init(mesh_rsn
, wpa_s
->own_addr
,
246 conf
->ieee80211w
, conf
->ocv
) < 0) {
247 mesh_rsn_deinit(mesh_rsn
);
252 bss
->wpa_auth
= mesh_rsn
->auth
;
254 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
255 while ((entry
= dl_list_last(&wpa_s
->mesh_external_pmksa_cache
,
256 struct external_pmksa_cache
,
260 ret
= wpa_auth_pmksa_add_entry(bss
->wpa_auth
,
262 dl_list_del(&entry
->list
);
268 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
270 ie
= wpa_auth_get_wpa_ie(mesh_rsn
->auth
, &ie_len
);
271 conf
->rsn_ie
= (u8
*) ie
;
272 conf
->rsn_ie_len
= ie_len
;
274 wpa_supplicant_rsn_supp_set_config(wpa_s
, wpa_s
->current_ssid
);
280 static int index_within_array(const int *array
, int idx
)
284 for (i
= 0; i
< idx
; i
++) {
293 static int mesh_rsn_sae_group(struct wpa_supplicant
*wpa_s
,
294 struct sae_data
*sae
)
296 int *groups
= wpa_s
->ifmsh
->bss
[0]->conf
->sae_groups
;
298 /* Configuration may have changed, so validate current index */
299 if (!index_within_array(groups
, wpa_s
->mesh_rsn
->sae_group_index
))
303 int group
= groups
[wpa_s
->mesh_rsn
->sae_group_index
];
307 if (sae_set_group(sae
, group
) == 0) {
308 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Selected SAE group %d",
312 wpa_s
->mesh_rsn
->sae_group_index
++;
319 static int mesh_rsn_build_sae_commit(struct wpa_supplicant
*wpa_s
,
320 struct wpa_ssid
*ssid
,
321 struct sta_info
*sta
)
323 const char *password
;
325 password
= ssid
->sae_password
;
327 password
= ssid
->passphrase
;
329 wpa_msg(wpa_s
, MSG_DEBUG
, "SAE: No password available");
333 if (mesh_rsn_sae_group(wpa_s
, sta
->sae
) < 0) {
334 wpa_msg(wpa_s
, MSG_DEBUG
, "SAE: Failed to select group");
338 if (sta
->sae
->tmp
&& !sta
->sae
->tmp
->pw_id
&& ssid
->sae_password_id
) {
339 sta
->sae
->tmp
->pw_id
= os_strdup(ssid
->sae_password_id
);
340 if (!sta
->sae
->tmp
->pw_id
)
343 return sae_prepare_commit(wpa_s
->own_addr
, sta
->addr
,
344 (u8
*) password
, os_strlen(password
),
345 ssid
->sae_password_id
,
350 /* initiate new SAE authentication with sta */
351 int mesh_rsn_auth_sae_sta(struct wpa_supplicant
*wpa_s
,
352 struct sta_info
*sta
)
354 struct hostapd_data
*hapd
= wpa_s
->ifmsh
->bss
[0];
355 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
356 struct rsn_pmksa_cache_entry
*pmksa
;
361 wpa_msg(wpa_s
, MSG_DEBUG
,
362 "AUTH: No current_ssid known to initiate new SAE");
367 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
368 if (sta
->sae
== NULL
)
372 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
, NULL
);
375 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
378 wpa_printf(MSG_ERROR
,
379 "mesh: Failed to initialize RSN state machine");
383 wpa_printf(MSG_DEBUG
,
384 "AUTH: Mesh PMKSA cache entry found for " MACSTR
385 " - try to use PMKSA caching instead of new SAE authentication",
387 wpa_auth_pmksa_set_to_sm(pmksa
, sta
->wpa_sm
, hapd
->wpa_auth
,
388 sta
->sae
->pmkid
, sta
->sae
->pmk
);
389 sae_accept_sta(hapd
, sta
);
390 sta
->mesh_sae_pmksa_caching
= 1;
393 sta
->mesh_sae_pmksa_caching
= 0;
395 if (mesh_rsn_build_sae_commit(wpa_s
, ssid
, sta
))
398 wpa_msg(wpa_s
, MSG_DEBUG
,
399 "AUTH: started authentication with SAE peer: " MACSTR
,
402 ret
= auth_sae_init_committed(hapd
, sta
);
406 eloop_cancel_timeout(mesh_auth_timer
, wpa_s
, sta
);
407 rnd
= rand() % MESH_AUTH_TIMEOUT
;
408 eloop_register_timeout(MESH_AUTH_TIMEOUT
+ rnd
, 0, mesh_auth_timer
,
414 void mesh_rsn_get_pmkid(struct mesh_rsn
*rsn
, struct sta_info
*sta
, u8
*pmkid
)
416 os_memcpy(pmkid
, sta
->sae
->pmkid
, SAE_PMKID_LEN
);
421 mesh_rsn_derive_aek(struct mesh_rsn
*rsn
, struct sta_info
*sta
)
423 u8
*myaddr
= rsn
->wpa_s
->own_addr
;
424 u8
*peer
= sta
->addr
;
426 u8 context
[RSN_SELECTOR_LEN
+ 2 * ETH_ALEN
], *ptr
= context
;
429 * AEK = KDF-Hash-256(PMK, "AEK Derivation", Selected AKM Suite ||
430 * min(localMAC, peerMAC) || max(localMAC, peerMAC))
432 /* Selected AKM Suite: SAE */
433 RSN_SELECTOR_PUT(ptr
, RSN_AUTH_KEY_MGMT_SAE
);
434 ptr
+= RSN_SELECTOR_LEN
;
436 if (os_memcmp(myaddr
, peer
, ETH_ALEN
) < 0) {
443 os_memcpy(ptr
, addr1
, ETH_ALEN
);
445 os_memcpy(ptr
, addr2
, ETH_ALEN
);
447 sha256_prf(sta
->sae
->pmk
, sizeof(sta
->sae
->pmk
), "AEK Derivation",
448 context
, sizeof(context
), sta
->aek
, sizeof(sta
->aek
));
452 /* derive mesh temporal key from pmk */
453 int mesh_rsn_derive_mtk(struct wpa_supplicant
*wpa_s
, struct sta_info
*sta
)
457 u8
*myaddr
= wpa_s
->own_addr
;
458 u8
*peer
= sta
->addr
;
459 u8 context
[2 * WPA_NONCE_LEN
+ 2 * 2 + RSN_SELECTOR_LEN
+ 2 * ETH_ALEN
];
462 * MTK = KDF-Hash-Length(PMK, "Temporal Key Derivation", min(localNonce,
463 * peerNonce) || max(localNonce, peerNonce) || min(localLinkID,
464 * peerLinkID) || max(localLinkID, peerLinkID) || Selected AKM Suite ||
465 * min(localMAC, peerMAC) || max(localMAC, peerMAC))
468 if (os_memcmp(sta
->my_nonce
, sta
->peer_nonce
, WPA_NONCE_LEN
) < 0) {
470 max
= sta
->peer_nonce
;
472 min
= sta
->peer_nonce
;
475 os_memcpy(ptr
, min
, WPA_NONCE_LEN
);
476 ptr
+= WPA_NONCE_LEN
;
477 os_memcpy(ptr
, max
, WPA_NONCE_LEN
);
478 ptr
+= WPA_NONCE_LEN
;
480 if (sta
->my_lid
< sta
->peer_lid
) {
481 WPA_PUT_LE16(ptr
, sta
->my_lid
);
483 WPA_PUT_LE16(ptr
, sta
->peer_lid
);
486 WPA_PUT_LE16(ptr
, sta
->peer_lid
);
488 WPA_PUT_LE16(ptr
, sta
->my_lid
);
492 /* Selected AKM Suite: SAE */
493 RSN_SELECTOR_PUT(ptr
, RSN_AUTH_KEY_MGMT_SAE
);
494 ptr
+= RSN_SELECTOR_LEN
;
496 if (os_memcmp(myaddr
, peer
, ETH_ALEN
) < 0) {
503 os_memcpy(ptr
, min
, ETH_ALEN
);
505 os_memcpy(ptr
, max
, ETH_ALEN
);
507 sta
->mtk_len
= wpa_cipher_key_len(wpa_s
->mesh_rsn
->pairwise_cipher
);
508 sha256_prf(sta
->sae
->pmk
, SAE_PMK_LEN
,
509 "Temporal Key Derivation", context
, sizeof(context
),
510 sta
->mtk
, sta
->mtk_len
);
515 void mesh_rsn_init_ampe_sta(struct wpa_supplicant
*wpa_s
, struct sta_info
*sta
)
517 if (random_get_bytes(sta
->my_nonce
, WPA_NONCE_LEN
) < 0) {
518 wpa_printf(MSG_INFO
, "mesh: Failed to derive random nonce");
519 /* TODO: How to handle this more cleanly? */
521 os_memset(sta
->peer_nonce
, 0, WPA_NONCE_LEN
);
522 mesh_rsn_derive_aek(wpa_s
->mesh_rsn
, sta
);
526 /* insert AMPE and encrypted MIC at @ie.
527 * @mesh_rsn: mesh RSN context
528 * @sta: STA we're sending to
529 * @cat: pointer to category code in frame header.
530 * @buf: wpabuf to add encrypted AMPE and MIC to.
532 int mesh_rsn_protect_frame(struct mesh_rsn
*rsn
, struct sta_info
*sta
,
533 const u8
*cat
, struct wpabuf
*buf
)
535 struct ieee80211_ampe_ie
*ampe
;
536 u8
const *ie
= wpabuf_head_u8(buf
) + wpabuf_len(buf
);
537 u8
*ampe_ie
, *pos
, *mic_payload
;
538 const u8
*aad
[] = { rsn
->wpa_s
->own_addr
, sta
->addr
, cat
};
539 const size_t aad_len
[] = { ETH_ALEN
, ETH_ALEN
, ie
- cat
};
544 if (cat
[1] == PLINK_OPEN
)
545 len
+= rsn
->mgtk_len
+ WPA_KEY_RSC_LEN
+ 4;
546 if (cat
[1] == PLINK_OPEN
&& rsn
->igtk_len
)
547 len
+= 2 + 6 + rsn
->igtk_len
;
549 if (2 + AES_BLOCK_SIZE
+ 2 + len
> wpabuf_tailroom(buf
)) {
550 wpa_printf(MSG_ERROR
, "protect frame: buffer too small");
554 ampe_ie
= os_zalloc(2 + len
);
556 wpa_printf(MSG_ERROR
, "protect frame: out of memory");
561 ampe_ie
[0] = WLAN_EID_AMPE
;
563 ampe
= (struct ieee80211_ampe_ie
*) (ampe_ie
+ 2);
565 RSN_SELECTOR_PUT(ampe
->selected_pairwise_suite
,
566 RSN_CIPHER_SUITE_CCMP
);
567 os_memcpy(ampe
->local_nonce
, sta
->my_nonce
, WPA_NONCE_LEN
);
568 os_memcpy(ampe
->peer_nonce
, sta
->peer_nonce
, WPA_NONCE_LEN
);
570 pos
= (u8
*) (ampe
+ 1);
571 if (cat
[1] != PLINK_OPEN
)
574 /* TODO: Key Replay Counter[8] optionally for
575 * Mesh Group Key Inform/Acknowledge frames */
577 /* TODO: static mgtk for now since we don't support rekeying! */
580 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
582 os_memcpy(pos
, rsn
->mgtk
, rsn
->mgtk_len
);
583 pos
+= rsn
->mgtk_len
;
584 wpa_drv_get_seqnum(rsn
->wpa_s
, NULL
, rsn
->mgtk_key_id
, pos
);
585 pos
+= WPA_KEY_RSC_LEN
;
586 /* Use fixed GTKExpirationTime for now */
587 WPA_PUT_LE32(pos
, 0xffffffff);
591 * IGTKdata[variable]:
592 * Key ID[2], IPN[6], IGTK[variable]
595 WPA_PUT_LE16(pos
, rsn
->igtk_key_id
);
597 wpa_drv_get_seqnum(rsn
->wpa_s
, NULL
, rsn
->igtk_key_id
, pos
);
599 os_memcpy(pos
, rsn
->igtk
, rsn
->igtk_len
);
603 wpa_hexdump_key(MSG_DEBUG
, "mesh: Plaintext AMPE element",
607 wpabuf_put_u8(buf
, WLAN_EID_MIC
);
608 wpabuf_put_u8(buf
, AES_BLOCK_SIZE
);
609 /* MIC field is output ciphertext */
611 /* encrypt after MIC */
612 mic_payload
= wpabuf_put(buf
, 2 + len
+ AES_BLOCK_SIZE
);
614 if (aes_siv_encrypt(sta
->aek
, sizeof(sta
->aek
), ampe_ie
, 2 + len
, 3,
615 aad
, aad_len
, mic_payload
)) {
616 wpa_printf(MSG_ERROR
, "protect frame: failed to encrypt");
626 int mesh_rsn_process_ampe(struct wpa_supplicant
*wpa_s
, struct sta_info
*sta
,
627 struct ieee802_11_elems
*elems
, const u8
*cat
,
628 const u8
*chosen_pmk
,
629 const u8
*start
, size_t elems_len
)
632 struct ieee80211_ampe_ie
*ampe
;
633 u8 null_nonce
[WPA_NONCE_LEN
] = {};
636 u8
*ampe_buf
, *crypt
= NULL
, *pos
, *end
;
638 const u8
*aad
[] = { sta
->addr
, wpa_s
->own_addr
, cat
};
639 const size_t aad_len
[] = { ETH_ALEN
, ETH_ALEN
,
640 elems
->mic
? (elems
->mic
- 2) - cat
: 0 };
644 struct hostapd_data
*hapd
= wpa_s
->ifmsh
->bss
[0];
646 if (!wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
, NULL
)) {
648 "Mesh RSN: SAE is not prepared yet");
651 mesh_rsn_auth_sae_sta(wpa_s
, sta
);
656 os_memcmp(chosen_pmk
, sta
->sae
->pmkid
, PMKID_LEN
) != 0)) {
657 wpa_msg(wpa_s
, MSG_DEBUG
,
658 "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)");
662 if (!elems
->mic
|| elems
->mic_len
< AES_BLOCK_SIZE
) {
663 wpa_msg(wpa_s
, MSG_DEBUG
, "Mesh RSN: missing mic ie");
667 ampe_buf
= (u8
*) elems
->mic
+ elems
->mic_len
;
668 if ((int) elems_len
< ampe_buf
- start
)
671 crypt_len
= elems_len
- (elems
->mic
- start
);
672 if (crypt_len
< 2 + AES_BLOCK_SIZE
) {
673 wpa_msg(wpa_s
, MSG_DEBUG
, "Mesh RSN: missing ampe ie");
677 /* crypt is modified by siv_decrypt */
678 crypt
= os_zalloc(crypt_len
);
680 wpa_printf(MSG_ERROR
, "Mesh RSN: out of memory");
685 os_memcpy(crypt
, elems
->mic
, crypt_len
);
687 if (aes_siv_decrypt(sta
->aek
, sizeof(sta
->aek
), crypt
, crypt_len
, 3,
688 aad
, aad_len
, ampe_buf
)) {
689 wpa_printf(MSG_ERROR
, "Mesh RSN: frame verification failed!");
694 crypt_len
-= AES_BLOCK_SIZE
;
695 wpa_hexdump_key(MSG_DEBUG
, "mesh: Decrypted AMPE element",
696 ampe_buf
, crypt_len
);
698 ampe_eid
= *ampe_buf
++;
699 ampe_ie_len
= *ampe_buf
++;
701 if (ampe_eid
!= WLAN_EID_AMPE
||
702 (size_t) 2 + ampe_ie_len
> crypt_len
||
703 ampe_ie_len
< sizeof(struct ieee80211_ampe_ie
)) {
704 wpa_msg(wpa_s
, MSG_DEBUG
, "Mesh RSN: invalid ampe ie");
709 ampe
= (struct ieee80211_ampe_ie
*) ampe_buf
;
710 pos
= (u8
*) (ampe
+ 1);
711 end
= ampe_buf
+ ampe_ie_len
;
712 if (os_memcmp(ampe
->peer_nonce
, null_nonce
, WPA_NONCE_LEN
) != 0 &&
713 os_memcmp(ampe
->peer_nonce
, sta
->my_nonce
, WPA_NONCE_LEN
) != 0) {
714 wpa_msg(wpa_s
, MSG_DEBUG
, "Mesh RSN: invalid peer nonce");
718 os_memcpy(sta
->peer_nonce
, ampe
->local_nonce
,
719 sizeof(ampe
->local_nonce
));
721 /* TODO: Key Replay Counter[8] in Mesh Group Key Inform/Acknowledge
725 * GTKdata shall not be included in Mesh Peering Confirm. While the
726 * standard does not state the same about IGTKdata, that same constraint
727 * needs to apply for it. It makes no sense to include the keys in Mesh
728 * Peering Close frames either, so while the standard does not seem to
729 * have a shall statement for these, they are described without
730 * mentioning GTKdata.
732 * An earlier implementation used to add GTKdata to both Mesh Peering
733 * Open and Mesh Peering Confirm frames, so ignore the possibly present
734 * GTKdata frame without rejecting the frame as a backwards
735 * compatibility mechanism.
737 if (cat
[1] != PLINK_OPEN
) {
739 wpa_hexdump_key(MSG_DEBUG
,
740 "mesh: Ignore unexpected GTKdata(etc.) fields in the end of AMPE element in Mesh Peering Confirm/Close",
748 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
750 sta
->mgtk_key_id
= 1; /* FIX: Where to get Key ID? */
751 key_len
= wpa_cipher_key_len(wpa_s
->mesh_rsn
->group_cipher
);
752 if ((int) key_len
+ WPA_KEY_RSC_LEN
+ 4 > end
- pos
) {
753 wpa_dbg(wpa_s
, MSG_DEBUG
, "mesh: Truncated AMPE element");
757 sta
->mgtk_len
= key_len
;
758 os_memcpy(sta
->mgtk
, pos
, sta
->mgtk_len
);
759 wpa_hexdump_key(MSG_DEBUG
, "mesh: GTKdata - MGTK",
760 sta
->mgtk
, sta
->mgtk_len
);
761 pos
+= sta
->mgtk_len
;
762 wpa_hexdump(MSG_DEBUG
, "mesh: GTKdata - MGTK - Key RSC",
763 pos
, WPA_KEY_RSC_LEN
);
764 os_memcpy(sta
->mgtk_rsc
, pos
, sizeof(sta
->mgtk_rsc
));
765 pos
+= WPA_KEY_RSC_LEN
;
766 wpa_printf(MSG_DEBUG
,
767 "mesh: GTKdata - MGTK - GTKExpirationTime: %u seconds",
772 * IGTKdata[variable]:
773 * Key ID[2], IPN[6], IGTK[variable]
775 key_len
= wpa_cipher_key_len(wpa_s
->mesh_rsn
->mgmt_group_cipher
);
776 if (end
- pos
>= (int) (2 + 6 + key_len
)) {
777 sta
->igtk_key_id
= WPA_GET_LE16(pos
);
778 wpa_printf(MSG_DEBUG
, "mesh: IGTKdata - Key ID %u",
781 os_memcpy(sta
->igtk_rsc
, pos
, sizeof(sta
->igtk_rsc
));
782 wpa_hexdump(MSG_DEBUG
, "mesh: IGTKdata - IPN",
783 sta
->igtk_rsc
, sizeof(sta
->igtk_rsc
));
785 os_memcpy(sta
->igtk
, pos
, key_len
);
786 sta
->igtk_len
= key_len
;
787 wpa_hexdump_key(MSG_DEBUG
, "mesh: IGTKdata - IGTK",
788 sta
->igtk
, sta
->igtk_len
);