Revert "Revert "[wpa_supplicant] cumilative patch from commit 3a..."
Revert submission 28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR
Reason for revert: Fixed the regression issue (ag/28389573)
Reverted changes: /q/submissionid:28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR
Bug: 329004037
Test: Turn ON/OFF SoftAp multiple times
Change-Id: Ibfff2a847be5678f1a6d77e28506a05936812a91
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index a662201..3002d91 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -194,6 +194,9 @@
if (!wpa_auth->cb->get_seqnum)
return -1;
+#ifdef CONFIG_TESTING_OPTIONS
+ os_memset(seq, 0, WPA_KEY_RSC_LEN);
+#endif /* CONFIG_TESTING_OPTIONS */
res = wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
#ifdef CONFIG_TESTING_OPTIONS
if (!addr && idx < 4 && wpa_auth->conf.gtk_rsc_override_set) {
@@ -599,6 +602,15 @@
}
#endif /* CONFIG_P2P */
+ if (conf->tx_bss_auth && conf->beacon_prot) {
+ conf->tx_bss_auth->non_tx_beacon_prot = true;
+ if (!conf->tx_bss_auth->conf.beacon_prot)
+ conf->tx_bss_auth->conf.beacon_prot = true;
+ if (!conf->tx_bss_auth->conf.group_mgmt_cipher)
+ conf->tx_bss_auth->conf.group_mgmt_cipher =
+ conf->group_mgmt_cipher;
+ }
+
return wpa_auth;
}
@@ -618,6 +630,17 @@
}
+static void wpa_auth_free_conf(struct wpa_auth_config *conf)
+{
+#ifdef CONFIG_TESTING_OPTIONS
+ wpabuf_free(conf->eapol_m1_elements);
+ conf->eapol_m1_elements = NULL;
+ wpabuf_free(conf->eapol_m3_elements);
+ conf->eapol_m3_elements = NULL;
+#endif /* CONFIG_TESTING_OPTIONS */
+}
+
+
/**
* wpa_deinit - Deinitialize WPA authenticator
* @wpa_auth: Pointer to WPA authenticator data from wpa_init()
@@ -651,6 +674,7 @@
bin_clear_free(prev, sizeof(*prev));
}
+ wpa_auth_free_conf(&wpa_auth->conf);
os_free(wpa_auth);
}
@@ -668,6 +692,7 @@
if (!wpa_auth)
return 0;
+ wpa_auth_free_conf(&wpa_auth->conf);
os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
if (wpa_auth_gen_wpa_ie(wpa_auth)) {
wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
@@ -900,19 +925,70 @@
struct wpa_state_machine *sm,
struct wpa_eapol_ie_parse *kde)
{
- struct wpa_ie_data ie;
+ struct wpa_ie_data ie, assoc_ie;
struct rsn_mdie *mdie;
+ unsigned int i, j;
+ bool found = false;
+
+ /* Verify that PMKR1Name from EAPOL-Key message 2/4 matches the value
+ * we derived. */
if (wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0 ||
- ie.num_pmkid != 1 || !ie.pmkid) {
+ ie.num_pmkid < 1 || !ie.pmkid) {
wpa_printf(MSG_DEBUG,
"FT: No PMKR1Name in FT 4-way handshake message 2/4");
return -1;
}
- os_memcpy(sm->sup_pmk_r1_name, ie.pmkid, PMKID_LEN);
- wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Supplicant",
- sm->sup_pmk_r1_name, PMKID_LEN);
+ if (wpa_parse_wpa_ie_rsn(sm->wpa_ie, sm->wpa_ie_len, &assoc_ie) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "FT: Could not parse (Re)Association Request frame RSNE");
+ os_memset(&assoc_ie, 0, sizeof(assoc_ie));
+ /* Continue to allow PMKR1Name matching to be done to cover the
+ * case where it is the only listed PMKID. */
+ }
+
+ for (i = 0; i < ie.num_pmkid; i++) {
+ const u8 *pmkid = ie.pmkid + i * PMKID_LEN;
+
+ if (os_memcmp_const(pmkid, sm->pmk_r1_name,
+ WPA_PMK_NAME_LEN) == 0) {
+ wpa_printf(MSG_DEBUG,
+ "FT: RSNE[PMKID[%u]] from supplicant matches PMKR1Name",
+ i);
+ found = true;
+ } else {
+ for (j = 0; j < assoc_ie.num_pmkid; j++) {
+ if (os_memcmp(pmkid,
+ assoc_ie.pmkid + j * PMKID_LEN,
+ PMKID_LEN) == 0)
+ break;
+ }
+
+ if (j == assoc_ie.num_pmkid) {
+ wpa_printf(MSG_DEBUG,
+ "FT: RSNE[PMKID[%u]] from supplicant is neither PMKR1Name nor included in AssocReq",
+ i);
+ found = false;
+ break;
+ }
+ wpa_printf(MSG_DEBUG,
+ "FT: RSNE[PMKID[%u]] from supplicant is not PMKR1Name, but matches a PMKID in AssocReq",
+ i);
+ }
+ }
+
+ if (!found) {
+ wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_DEBUG,
+ "PMKR1Name mismatch in FT 4-way handshake");
+ wpa_hexdump(MSG_DEBUG,
+ "FT: PMKIDs/PMKR1Name from Supplicant",
+ ie.pmkid, ie.num_pmkid * PMKID_LEN);
+ wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
+ sm->pmk_r1_name, WPA_PMK_NAME_LEN);
+ return -1;
+ }
if (!kde->mdie || !kde->ftie) {
wpa_printf(MSG_DEBUG,
@@ -1076,28 +1152,166 @@
}
+enum eapol_key_msg { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST };
+
+static bool wpa_auth_valid_key_desc_ver(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm, u16 ver)
+{
+ if (ver > WPA_KEY_INFO_TYPE_AES_128_CMAC) {
+ wpa_printf(MSG_INFO, "RSN: " MACSTR
+ " used undefined Key Descriptor Version %d",
+ MAC2STR(wpa_auth_get_spa(sm)), ver);
+ return false;
+ }
+
+ if (!wpa_use_akm_defined(sm->wpa_key_mgmt) &&
+ wpa_use_cmac(sm->wpa_key_mgmt) &&
+ ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
+ wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_WARNING,
+ "advertised support for AES-128-CMAC, but did not use it");
+ return false;
+ }
+
+ if (sm->pairwise != WPA_CIPHER_TKIP &&
+ !wpa_use_akm_defined(sm->wpa_key_mgmt) &&
+ !wpa_use_cmac(sm->wpa_key_mgmt) &&
+ ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
+ wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_WARNING,
+ "did not use HMAC-SHA1-AES with CCMP/GCMP");
+ return false;
+ }
+
+ if (wpa_use_akm_defined(sm->wpa_key_mgmt) &&
+ ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
+ wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_WARNING,
+ "did not use EAPOL-Key descriptor version 0 as required for AKM-defined cases");
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool wpa_auth_valid_request_counter(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm,
+ const u8 *replay_counter)
+{
+
+ if (sm->req_replay_counter_used &&
+ os_memcmp(replay_counter, sm->req_replay_counter,
+ WPA_REPLAY_COUNTER_LEN) <= 0) {
+ wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_WARNING,
+ "received EAPOL-Key request with replayed counter");
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool wpa_auth_valid_counter(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm,
+ const struct wpa_eapol_key *key,
+ enum eapol_key_msg msg,
+ const char *msgtxt)
+{
+ int i;
+
+ if (msg == REQUEST)
+ return wpa_auth_valid_request_counter(wpa_auth, sm,
+ key->replay_counter);
+
+ if (wpa_replay_counter_valid(sm->key_replay, key->replay_counter))
+ return true;
+
+ if (msg == PAIRWISE_2 &&
+ wpa_replay_counter_valid(sm->prev_key_replay,
+ key->replay_counter) &&
+ sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
+ os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
+ /*
+ * Some supplicant implementations (e.g., Windows XP
+ * WZC) update SNonce for each EAPOL-Key 2/4. This
+ * breaks the workaround on accepting any of the
+ * pending requests, so allow the SNonce to be updated
+ * even if we have already sent out EAPOL-Key 3/4.
+ */
+ wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_DEBUG,
+ "Process SNonce update from STA based on retransmitted EAPOL-Key 1/4");
+ sm->update_snonce = 1;
+ os_memcpy(sm->alt_SNonce, sm->SNonce, WPA_NONCE_LEN);
+ sm->alt_snonce_valid = true;
+ os_memcpy(sm->alt_replay_counter,
+ sm->key_replay[0].counter,
+ WPA_REPLAY_COUNTER_LEN);
+ return true;
+ }
+
+ if (msg == PAIRWISE_4 && sm->alt_snonce_valid &&
+ sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
+ os_memcmp(key->replay_counter, sm->alt_replay_counter,
+ WPA_REPLAY_COUNTER_LEN) == 0) {
+ /*
+ * Supplicant may still be using the old SNonce since
+ * there was two EAPOL-Key 2/4 messages and they had
+ * different SNonce values.
+ */
+ wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_DEBUG,
+ "Try to process received EAPOL-Key 4/4 based on old Replay Counter and SNonce from an earlier EAPOL-Key 1/4");
+ return true;
+ }
+
+ if (msg == PAIRWISE_2 &&
+ wpa_replay_counter_valid(sm->prev_key_replay,
+ key->replay_counter) &&
+ sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) {
+ wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_DEBUG,
+ "ignore retransmitted EAPOL-Key %s - SNonce did not change",
+ msgtxt);
+ } else {
+ wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_DEBUG,
+ "received EAPOL-Key %s with unexpected replay counter",
+ msgtxt);
+ }
+ for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
+ if (!sm->key_replay[i].valid)
+ break;
+ wpa_hexdump(MSG_DEBUG, "pending replay counter",
+ sm->key_replay[i].counter,
+ WPA_REPLAY_COUNTER_LEN);
+ }
+ wpa_hexdump(MSG_DEBUG, "received replay counter",
+ key->replay_counter, WPA_REPLAY_COUNTER_LEN);
+ return false;
+}
+
+
void wpa_receive(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm,
u8 *data, size_t data_len)
{
struct ieee802_1x_hdr *hdr;
struct wpa_eapol_key *key;
- u16 key_info, key_data_length;
- enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST } msg;
- char *msgtxt;
- struct wpa_eapol_ie_parse kde;
+ u16 key_info, ver, key_data_length;
+ enum eapol_key_msg msg;
+ const char *msgtxt;
const u8 *key_data;
size_t keyhdrlen, mic_len;
u8 *mic;
- bool is_mld = false;
+ u8 *key_data_buf = NULL;
+ size_t key_data_buf_len = 0;
if (!wpa_auth || !wpa_auth->conf.wpa || !sm)
return;
-#ifdef CONFIG_IEEE80211BE
- is_mld = sm->mld_assoc_link_id >= 0;
-#endif /* CONFIG_IEEE80211BE */
-
wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL data", data, data_len);
mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
@@ -1167,11 +1381,31 @@
return;
}
- /* TODO: Make this more robust for distinguising EAPOL-Key msg 2/4 from
- * 4/4. Secure=1 is used in msg 2/4 when doing PTK rekeying, so the
- * MLD mechanism here does not work without the somewhat undesired check
- * on wpa_ptk_state.. Would likely need to decrypt Key Data first to be
- * able to know which message this is in MLO cases.. */
+ ver = key_info & WPA_KEY_INFO_TYPE_MASK;
+ if (!wpa_auth_valid_key_desc_ver(wpa_auth, sm, ver))
+ goto out;
+ if (mic_len > 0 && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
+ sm->PTK_valid &&
+ (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
+ ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
+ wpa_use_aes_key_wrap(sm->wpa_key_mgmt)) &&
+ key_data_length >= 8 && key_data_length % 8 == 0) {
+ key_data_length -= 8; /* AES-WRAP adds 8 bytes */
+ key_data_buf = os_malloc(key_data_length);
+ if (!key_data_buf)
+ goto out;
+ key_data_buf_len = key_data_length;
+ if (aes_unwrap(sm->PTK.kek, sm->PTK.kek_len,
+ key_data_length / 8, key_data, key_data_buf)) {
+ wpa_printf(MSG_INFO,
+ "RSN: AES unwrap failed - could not decrypt EAPOL-Key key data");
+ goto out;
+ }
+ key_data = key_data_buf;
+ wpa_hexdump_key(MSG_DEBUG, "RSN: Decrypted EAPOL-Key Key Data",
+ key_data, key_data_length);
+ }
+
if (key_info & WPA_KEY_INFO_REQUEST) {
msg = REQUEST;
msgtxt = "Request";
@@ -1179,10 +1413,13 @@
msg = GROUP_2;
msgtxt = "2/2 Group";
} else if (key_data_length == 0 ||
+ (sm->wpa == WPA_VERSION_WPA2 &&
+ (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ||
+ key_data_buf) &&
+ (key_info & WPA_KEY_INFO_SECURE) &&
+ !get_ie(key_data, key_data_length, WLAN_EID_RSN)) ||
(mic_len == 0 && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
- key_data_length == AES_BLOCK_SIZE) ||
- (is_mld && (key_info & WPA_KEY_INFO_SECURE) &&
- sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING)) {
+ key_data_length == AES_BLOCK_SIZE)) {
msg = PAIRWISE_4;
msgtxt = "4/4 Pairwise";
} else {
@@ -1190,127 +1427,15 @@
msgtxt = "2/4 Pairwise";
}
- if (msg == REQUEST || msg == PAIRWISE_2 || msg == PAIRWISE_4 ||
- msg == GROUP_2) {
- u16 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
- if (sm->pairwise == WPA_CIPHER_CCMP ||
- sm->pairwise == WPA_CIPHER_GCMP) {
- if (wpa_use_cmac(sm->wpa_key_mgmt) &&
- !wpa_use_akm_defined(sm->wpa_key_mgmt) &&
- ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
- wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_WARNING,
- "advertised support for AES-128-CMAC, but did not use it");
- return;
- }
+ if (!wpa_auth_valid_counter(wpa_auth, sm, key, msg, msgtxt))
+ goto out;
- if (!wpa_use_cmac(sm->wpa_key_mgmt) &&
- !wpa_use_akm_defined(sm->wpa_key_mgmt) &&
- ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
- wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_WARNING,
- "did not use HMAC-SHA1-AES with CCMP/GCMP");
- return;
- }
- }
-
- if (wpa_use_akm_defined(sm->wpa_key_mgmt) &&
- ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
- wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_WARNING,
- "did not use EAPOL-Key descriptor version 0 as required for AKM-defined cases");
- return;
- }
- }
-
- if (key_info & WPA_KEY_INFO_REQUEST) {
- if (sm->req_replay_counter_used &&
- os_memcmp(key->replay_counter, sm->req_replay_counter,
- WPA_REPLAY_COUNTER_LEN) <= 0) {
- wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_WARNING,
- "received EAPOL-Key request with replayed counter");
- return;
- }
- }
-
- if (!(key_info & WPA_KEY_INFO_REQUEST) &&
- !wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) {
- int i;
-
- if (msg == PAIRWISE_2 &&
- wpa_replay_counter_valid(sm->prev_key_replay,
- key->replay_counter) &&
- sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
- os_memcmp(sm->SNonce, key->key_nonce, WPA_NONCE_LEN) != 0)
- {
- /*
- * Some supplicant implementations (e.g., Windows XP
- * WZC) update SNonce for each EAPOL-Key 2/4. This
- * breaks the workaround on accepting any of the
- * pending requests, so allow the SNonce to be updated
- * even if we have already sent out EAPOL-Key 3/4.
- */
- wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_DEBUG,
- "Process SNonce update from STA based on retransmitted EAPOL-Key 1/4");
- sm->update_snonce = 1;
- os_memcpy(sm->alt_SNonce, sm->SNonce, WPA_NONCE_LEN);
- sm->alt_snonce_valid = true;
- os_memcpy(sm->alt_replay_counter,
- sm->key_replay[0].counter,
- WPA_REPLAY_COUNTER_LEN);
- goto continue_processing;
- }
-
- if (msg == PAIRWISE_4 && sm->alt_snonce_valid &&
- sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
- os_memcmp(key->replay_counter, sm->alt_replay_counter,
- WPA_REPLAY_COUNTER_LEN) == 0) {
- /*
- * Supplicant may still be using the old SNonce since
- * there was two EAPOL-Key 2/4 messages and they had
- * different SNonce values.
- */
- wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_DEBUG,
- "Try to process received EAPOL-Key 4/4 based on old Replay Counter and SNonce from an earlier EAPOL-Key 1/4");
- goto continue_processing;
- }
-
- if (msg == PAIRWISE_2 &&
- wpa_replay_counter_valid(sm->prev_key_replay,
- key->replay_counter) &&
- sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) {
- wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_DEBUG,
- "ignore retransmitted EAPOL-Key %s - SNonce did not change",
- msgtxt);
- } else {
- wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_DEBUG,
- "received EAPOL-Key %s with unexpected replay counter",
- msgtxt);
- }
- for (i = 0; i < RSNA_MAX_EAPOL_RETRIES; i++) {
- if (!sm->key_replay[i].valid)
- break;
- wpa_hexdump(MSG_DEBUG, "pending replay counter",
- sm->key_replay[i].counter,
- WPA_REPLAY_COUNTER_LEN);
- }
- wpa_hexdump(MSG_DEBUG, "received replay counter",
- key->replay_counter, WPA_REPLAY_COUNTER_LEN);
- return;
- }
-
-continue_processing:
#ifdef CONFIG_FILS
if (sm->wpa == WPA_VERSION_WPA2 && mic_len == 0 &&
!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
"WPA: Encr Key Data bit not set even though AEAD cipher is supposed to be used - drop frame");
- return;
+ goto out;
}
#endif /* CONFIG_FILS */
@@ -1324,7 +1449,7 @@
LOGGER_INFO,
"received EAPOL-Key msg 2/4 in invalid state (%d) - dropped",
sm->wpa_ptk_state);
- return;
+ goto out;
}
random_add_randomness(key->key_nonce, WPA_NONCE_LEN);
if (sm->group->reject_4way_hs_for_entropy) {
@@ -1342,7 +1467,7 @@
random_mark_pool_ready();
wpa_sta_disconnect(wpa_auth, sm->addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
- return;
+ goto out;
}
break;
case PAIRWISE_4:
@@ -1352,7 +1477,7 @@
LOGGER_INFO,
"received EAPOL-Key msg 4/4 in invalid state (%d) - dropped",
sm->wpa_ptk_state);
- return;
+ goto out;
}
break;
case GROUP_2:
@@ -1362,10 +1487,20 @@
LOGGER_INFO,
"received EAPOL-Key msg 2/2 in invalid state (%d) - dropped",
sm->wpa_ptk_group_state);
- return;
+ goto out;
}
break;
case REQUEST:
+ if (sm->wpa_ptk_state == WPA_PTK_PTKSTART ||
+ sm->wpa_ptk_state == WPA_PTK_PTKCALCNEGOTIATING ||
+ sm->wpa_ptk_state == WPA_PTK_PTKCALCNEGOTIATING2 ||
+ sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING) {
+ wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_INFO,
+ "received EAPOL-Key Request in invalid state (%d) - dropped",
+ sm->wpa_ptk_state);
+ goto out;
+ }
break;
}
@@ -1375,14 +1510,14 @@
if (key_info & WPA_KEY_INFO_ACK) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
"received invalid EAPOL-Key: Key Ack set");
- return;
+ goto out;
}
if (!wpa_key_mgmt_fils(sm->wpa_key_mgmt) &&
!(key_info & WPA_KEY_INFO_MIC)) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
"received invalid EAPOL-Key: Key MIC not set");
- return;
+ goto out;
}
#ifdef CONFIG_FILS
@@ -1390,7 +1525,7 @@
(key_info & WPA_KEY_INFO_MIC)) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
"received invalid EAPOL-Key: Key MIC set");
- return;
+ goto out;
}
#endif /* CONFIG_FILS */
@@ -1409,7 +1544,7 @@
"TEST: Ignore Key MIC failure for fuzz testing");
goto continue_fuzz;
#endif /* TEST_FUZZ */
- return;
+ goto out;
}
#ifdef CONFIG_FILS
if (!mic_len &&
@@ -1423,7 +1558,7 @@
"TEST: Ignore Key MIC failure for fuzz testing");
goto continue_fuzz;
#endif /* TEST_FUZZ */
- return;
+ goto out;
}
#endif /* CONFIG_FILS */
#ifdef TEST_FUZZ
@@ -1435,6 +1570,12 @@
}
if (key_info & WPA_KEY_INFO_REQUEST) {
+ if (!(key_info & WPA_KEY_INFO_SECURE)) {
+ wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
+ LOGGER_INFO,
+ "received EAPOL-Key request without Secure=1");
+ goto out;
+ }
if (sm->MICVerified) {
sm->req_replay_counter_used = 1;
os_memcpy(sm->req_replay_counter, key->replay_counter,
@@ -1443,28 +1584,19 @@
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
LOGGER_INFO,
"received EAPOL-Key request with invalid MIC");
- return;
+ goto out;
}
- /*
- * TODO: should decrypt key data field if encryption was used;
- * even though MAC address KDE is not normally encrypted,
- * supplicant is allowed to encrypt it.
- */
if (key_info & WPA_KEY_INFO_ERROR) {
if (wpa_receive_error_report(
wpa_auth, sm,
!(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0)
- return; /* STA entry was removed */
+ goto out; /* STA entry was removed */
} else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
LOGGER_INFO,
"received EAPOL-Key Request for new 4-Way Handshake");
wpa_request_new_ptk(sm);
- } else if (key_data_length > 0 &&
- wpa_parse_kde_ies(key_data, key_data_length,
- &kde) == 0 &&
- kde.mac_addr) {
} else {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm),
LOGGER_INFO,
@@ -1506,7 +1638,7 @@
os_free(sm->last_rx_eapol_key);
sm->last_rx_eapol_key = os_memdup(data, data_len);
if (!sm->last_rx_eapol_key)
- return;
+ goto out;
sm->last_rx_eapol_key_len = data_len;
sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE);
@@ -1515,6 +1647,9 @@
sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN);
wpa_sm_step(sm);
+
+out:
+ bin_clear_free(key_data_buf, key_data_buf_len);
}
@@ -2332,10 +2467,14 @@
SM_STATE(WPA_PTK, PTKSTART)
{
- u8 buf[2 * (2 + RSN_SELECTOR_LEN) + PMKID_LEN + ETH_ALEN];
+ u8 *buf;
+ size_t buf_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
u8 *pmkid = NULL;
size_t kde_len = 0;
u16 key_info;
+#ifdef CONFIG_TESTING_OPTIONS
+ struct wpa_auth_config *conf = &sm->wpa_auth->conf;
+#endif /* CONFIG_TESTING_OPTIONS */
SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk);
sm->PTKRequest = false;
@@ -2350,6 +2489,19 @@
return;
}
+#ifdef CONFIG_IEEE80211BE
+ if (sm->mld_assoc_link_id >= 0)
+ buf_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
+#endif /* CONFIG_IEEE80211BE */
+#ifdef CONFIG_TESTING_OPTIONS
+ if (conf->eapol_m1_elements)
+ buf_len += wpabuf_len(conf->eapol_m1_elements);
+#endif /* CONFIG_TESTING_OPTIONS */
+
+ buf = os_zalloc(buf_len);
+ if (!buf)
+ return;
+
wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
"sending 1/4 msg of 4-Way Handshake");
/*
@@ -2453,11 +2605,20 @@
}
#endif /* CONFIG_IEEE80211BE */
+#ifdef CONFIG_TESTING_OPTIONS
+ if (conf->eapol_m1_elements) {
+ os_memcpy(buf + kde_len, wpabuf_head(conf->eapol_m1_elements),
+ wpabuf_len(conf->eapol_m1_elements));
+ kde_len += wpabuf_len(conf->eapol_m1_elements);
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
key_info = WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE;
if (sm->pairwise_set && sm->wpa != WPA_VERSION_WPA)
key_info |= WPA_KEY_INFO_SECURE;
wpa_send_eapol(sm->wpa_auth, sm, key_info, NULL,
sm->ANonce, kde_len ? buf : NULL, kde_len, 0, 0);
+ os_free(buf);
}
@@ -3178,7 +3339,7 @@
/* MLD MAC address must be the same */
if (!kde->mac_addr ||
- os_memcmp(kde->mac_addr, sm->peer_mld_addr, ETH_ALEN) != 0) {
+ !ether_addr_equal(kde->mac_addr, sm->peer_mld_addr)) {
wpa_printf(MSG_DEBUG, "RSN: MLD: Invalid MLD address");
return -1;
}
@@ -3205,8 +3366,8 @@
return -1;
}
- if (os_memcmp(sm->mld_links[i].peer_addr, kde->mlo_link[i] + 1,
- ETH_ALEN) != 0) {
+ if (!ether_addr_equal(sm->mld_links[i].peer_addr,
+ kde->mlo_link[i] + 1)) {
wpa_printf(MSG_DEBUG,
"RSN: MLD: invalid MAC address=" MACSTR
" expected " MACSTR " (link ID %u)",
@@ -3240,7 +3401,7 @@
size_t pmk_len;
int ft;
const u8 *eapol_key_ie, *key_data, *mic;
- u16 key_data_length;
+ u16 key_info, ver, key_data_length;
size_t mic_len, eapol_key_ie_len;
struct ieee802_1x_hdr *hdr;
struct wpa_eapol_key *key;
@@ -3250,6 +3411,8 @@
u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN];
u8 pmk_r1[PMK_LEN_MAX];
size_t key_len;
+ u8 *key_data_buf = NULL;
+ size_t key_data_buf_len = 0;
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
sm->EAPOLKeyReceived = false;
@@ -3357,12 +3520,46 @@
hdr = (struct ieee802_1x_hdr *) sm->last_rx_eapol_key;
key = (struct wpa_eapol_key *) (hdr + 1);
mic = (u8 *) (key + 1);
+ key_info = WPA_GET_BE16(key->key_info);
key_data = mic + mic_len + 2;
key_data_length = WPA_GET_BE16(mic + mic_len);
if (key_data_length > sm->last_rx_eapol_key_len - sizeof(*hdr) -
sizeof(*key) - mic_len - 2)
goto out;
+ ver = key_info & WPA_KEY_INFO_TYPE_MASK;
+ if (mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
+ if (ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
+ ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
+ !wpa_use_aes_key_wrap(sm->wpa_key_mgmt)) {
+ wpa_printf(MSG_INFO,
+ "Unsupported EAPOL-Key Key Data field encryption");
+ goto out;
+ }
+
+ if (key_data_length < 8 || key_data_length % 8) {
+ wpa_printf(MSG_INFO,
+ "RSN: Unsupported AES-WRAP len %u",
+ key_data_length);
+ goto out;
+ }
+ key_data_length -= 8; /* AES-WRAP adds 8 bytes */
+ key_data_buf = os_malloc(key_data_length);
+ if (!key_data_buf)
+ goto out;
+ key_data_buf_len = key_data_length;
+ if (aes_unwrap(PTK.kek, PTK.kek_len, key_data_length / 8,
+ key_data, key_data_buf)) {
+ bin_clear_free(key_data_buf, key_data_buf_len);
+ wpa_printf(MSG_INFO,
+ "RSN: AES unwrap failed - could not decrypt EAPOL-Key key data");
+ goto out;
+ }
+ key_data = key_data_buf;
+ wpa_hexdump_key(MSG_DEBUG, "RSN: Decrypted EAPOL-Key Key Data",
+ key_data, key_data_length);
+ }
+
if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) {
wpa_auth_vlogger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
"received EAPOL-Key msg 2/4 with invalid Key Data contents");
@@ -3507,27 +3704,6 @@
return;
}
-#ifdef CONFIG_IEEE80211R_AP
- if (sm->wpa == WPA_VERSION_WPA2 && wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
- /*
- * Verify that PMKR1Name from EAPOL-Key message 2/4 matches
- * with the value we derived.
- */
- if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name,
- WPA_PMK_NAME_LEN) != 0) {
- wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm),
- LOGGER_DEBUG,
- "PMKR1Name mismatch in FT 4-way handshake");
- wpa_hexdump(MSG_DEBUG,
- "FT: PMKR1Name from Supplicant",
- sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN);
- wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
- sm->pmk_r1_name, WPA_PMK_NAME_LEN);
- goto out;
- }
- }
-#endif /* CONFIG_IEEE80211R_AP */
-
if (vlan_id && wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
wpa_auth_update_vlan(wpa_auth, sm->addr, vlan_id) < 0) {
wpa_sta_disconnect(wpa_auth, sm->addr,
@@ -3562,6 +3738,7 @@
out:
forced_memzero(pmk_r0, sizeof(pmk_r0));
forced_memzero(pmk_r1, sizeof(pmk_r1));
+ bin_clear_free(key_data_buf, key_data_buf_len);
}
@@ -3575,14 +3752,18 @@
static int ieee80211w_kde_len(struct wpa_state_machine *sm)
{
size_t len = 0;
+ struct wpa_authenticator *wpa_auth = sm->wpa_auth;
if (sm->mgmt_frame_prot) {
len += 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN;
- len += wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
+ len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
}
+
+ if (wpa_auth->conf.tx_bss_auth)
+ wpa_auth = wpa_auth->conf.tx_bss_auth;
if (sm->mgmt_frame_prot && sm->wpa_auth->conf.beacon_prot) {
len += 2 + RSN_SELECTOR_LEN + WPA_BIGTK_KDE_PREFIX_LEN;
- len += wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
+ len += wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
}
return len;
@@ -3595,7 +3776,8 @@
struct wpa_bigtk_kde bigtk;
struct wpa_group *gsm = sm->group;
u8 rsc[WPA_KEY_RSC_LEN];
- struct wpa_auth_config *conf = &sm->wpa_auth->conf;
+ struct wpa_authenticator *wpa_auth = sm->wpa_auth;
+ struct wpa_auth_config *conf = &wpa_auth->conf;
size_t len = wpa_cipher_key_len(conf->group_mgmt_cipher);
if (!sm->mgmt_frame_prot)
@@ -3627,7 +3809,14 @@
NULL, 0);
forced_memzero(&igtk, sizeof(igtk));
- if (!conf->beacon_prot)
+ if (wpa_auth->conf.tx_bss_auth) {
+ wpa_auth = wpa_auth->conf.tx_bss_auth;
+ conf = &wpa_auth->conf;
+ len = wpa_cipher_key_len(conf->group_mgmt_cipher);
+ gsm = wpa_auth->group;
+ }
+
+ if (!sm->wpa_auth->conf.beacon_prot)
return pos;
bigtk.keyid[0] = gsm->GN_bigtk;
@@ -3785,6 +3974,11 @@
if (!beacon_prot)
return;
+ if (a->conf.tx_bss_auth) {
+ a = a->conf.tx_bss_auth;
+ gsm = a->group;
+ }
+
info->bigtkidx = gsm->GN_bigtk;
info->bigtk = gsm->BIGTK[gsm->GN_bigtk - 6];
@@ -3807,6 +4001,7 @@
static size_t wpa_auth_ml_group_kdes_len(struct wpa_state_machine *sm)
{
+ struct wpa_authenticator *wpa_auth = sm->wpa_auth;
struct wpa_group *gsm = sm->group;
size_t gtk_len = gsm->GTK_len;
size_t igtk_len;
@@ -3825,10 +4020,15 @@
return kde_len;
/* MLO IGTK KDE for each link */
- igtk_len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
+ igtk_len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
kde_len += n_links * (2 + RSN_SELECTOR_LEN + 2 + 6 + 1 + igtk_len);
- if (!sm->wpa_auth->conf.beacon_prot)
+ if (wpa_auth->conf.tx_bss_auth) {
+ wpa_auth = wpa_auth->conf.tx_bss_auth;
+ igtk_len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
+ }
+
+ if (!wpa_auth->conf.beacon_prot)
return kde_len;
/* MLO BIGTK KDE for each link */
@@ -3865,7 +4065,8 @@
/* Add MLO GTK KDEs */
for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
- if (!sm->mld_links[link_id].valid)
+ if (!sm->mld_links[link_id].valid ||
+ !ml_key_info.links[i].gtk_len)
continue;
wpa_printf(MSG_DEBUG, "RSN: MLO GTK: link=%u", link_id);
@@ -3897,7 +4098,8 @@
/* Add MLO IGTK KDEs */
for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
- if (!sm->mld_links[link_id].valid)
+ if (!sm->mld_links[link_id].valid ||
+ !ml_key_info.links[i].igtk_len)
continue;
wpa_printf(MSG_DEBUG, "RSN: MLO IGTK: link=%u", link_id);
@@ -3936,7 +4138,9 @@
/* Add MLO BIGTK KDEs */
for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
- if (!sm->mld_links[link_id].valid)
+ if (!sm->mld_links[link_id].valid ||
+ !ml_key_info.links[i].bigtk ||
+ !ml_key_info.links[i].igtk_len)
continue;
wpa_printf(MSG_DEBUG, "RSN: MLO BIGTK: link=%u", link_id);
@@ -4233,6 +4437,11 @@
kde_len += wpa_auth_ml_kdes_len(sm);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (conf->eapol_m3_elements)
+ kde_len += wpabuf_len(conf->eapol_m3_elements);
+#endif /* CONFIG_TESTING_OPTIONS */
+
kde = os_malloc(kde_len);
if (!kde)
goto done;
@@ -4248,7 +4457,7 @@
size_t elen;
elen = pos - kde;
- res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name);
+ res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name, true);
if (res < 0) {
wpa_printf(MSG_ERROR,
"FT: Failed to insert PMKR1Name into RSN IE in EAPOL-Key data");
@@ -4347,6 +4556,17 @@
pos = wpa_auth_ml_kdes(sm, pos);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (conf->eapol_m3_elements) {
+ os_memcpy(pos, wpabuf_head(conf->eapol_m3_elements),
+ wpabuf_len(conf->eapol_m3_elements));
+ pos += wpabuf_len(conf->eapol_m3_elements);
+ }
+
+ if (conf->eapol_m3_no_encrypt)
+ encr = 0;
+#endif /* CONFIG_TESTING_OPTIONS */
+
wpa_send_eapol(sm->wpa_auth, sm,
(secure ? WPA_KEY_INFO_SECURE : 0) |
(wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len) ?
@@ -4398,7 +4618,7 @@
/* MLD MAC address must be the same */
if (!kde.mac_addr ||
- os_memcmp(kde.mac_addr, sm->peer_mld_addr, ETH_ALEN) != 0) {
+ !ether_addr_equal(kde.mac_addr, sm->peer_mld_addr)) {
wpa_printf(MSG_DEBUG,
"MLD: Mismatching or missing MLD address in EAPOL-Key msg 4/4");
return -1;
@@ -4732,7 +4952,8 @@
return;
kde = pos = kde_buf;
- wpa_auth_ml_group_kdes(sm, pos);
+ pos = wpa_auth_ml_group_kdes(sm, pos);
+ kde_len = pos - kde_buf;
}
#endif /* CONFIG_IEEE80211BE */
} else {
@@ -4912,19 +5133,30 @@
group->IGTK[group->GN_igtk - 4], len);
}
- if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
- conf->beacon_prot) {
- len = wpa_cipher_key_len(conf->group_mgmt_cipher);
- os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
- inc_byte_array(group->Counter, WPA_NONCE_LEN);
- if (wpa_gmk_to_gtk(group->GMK, "BIGTK key expansion",
- wpa_auth->addr, group->GNonce,
- group->BIGTK[group->GN_bigtk - 6], len) < 0)
- ret = -1;
- wpa_hexdump_key(MSG_DEBUG, "BIGTK",
- group->BIGTK[group->GN_bigtk - 6], len);
+ if (!wpa_auth->non_tx_beacon_prot &&
+ conf->ieee80211w == NO_MGMT_FRAME_PROTECTION)
+ return ret;
+ if (!conf->beacon_prot)
+ return ret;
+
+ if (wpa_auth->conf.tx_bss_auth) {
+ group = wpa_auth->conf.tx_bss_auth->group;
+ if (group->bigtk_set)
+ return ret;
+ wpa_printf(MSG_DEBUG, "Set up BIGTK for TX BSS");
}
+ len = wpa_cipher_key_len(conf->group_mgmt_cipher);
+ os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
+ inc_byte_array(group->Counter, WPA_NONCE_LEN);
+ if (wpa_gmk_to_gtk(group->GMK, "BIGTK key expansion",
+ wpa_auth->addr, group->GNonce,
+ group->BIGTK[group->GN_bigtk - 6], len) < 0)
+ return -1;
+ group->bigtk_set = true;
+ wpa_hexdump_key(MSG_DEBUG, "BIGTK",
+ group->BIGTK[group->GN_bigtk - 6], len);
+
return ret;
}
@@ -5085,9 +5317,10 @@
int wpa_wnmsleep_bigtk_subelem(struct wpa_state_machine *sm, u8 *pos)
{
- struct wpa_group *gsm = sm->group;
+ struct wpa_authenticator *wpa_auth = sm->wpa_auth;
+ struct wpa_group *gsm = wpa_auth->group;
u8 *start = pos;
- size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
+ size_t len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
/*
* BIGTK subelement:
@@ -5097,7 +5330,7 @@
*pos++ = 2 + 6 + len;
WPA_PUT_LE16(pos, gsm->GN_bigtk);
pos += 2;
- if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_bigtk, pos) != 0)
+ if (wpa_auth_get_seqnum(wpa_auth, NULL, gsm->GN_bigtk, pos) != 0)
return 0;
pos += 6;
@@ -5187,12 +5420,21 @@
KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
- if (ret == 0 && conf->beacon_prot &&
- wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
+ if (ret || !conf->beacon_prot)
+ return ret;
+ if (wpa_auth->conf.tx_bss_auth) {
+ wpa_auth = wpa_auth->conf.tx_bss_auth;
+ group = wpa_auth->group;
+ if (!group->bigtk_set || group->bigtk_configured)
+ return ret;
+ }
+ if (wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
broadcast_ether_addr, group->GN_bigtk,
group->BIGTK[group->GN_bigtk - 6], len,
KEY_FLAG_GROUP_TX_DEFAULT) < 0)
ret = -1;
+ else
+ group->bigtk_configured = true;
}
return ret;
@@ -5337,9 +5579,11 @@
tmp = group->GM_igtk;
group->GM_igtk = group->GN_igtk;
group->GN_igtk = tmp;
- tmp = group->GM_bigtk;
- group->GM_bigtk = group->GN_bigtk;
- group->GN_bigtk = tmp;
+ if (!wpa_auth->conf.tx_bss_auth) {
+ tmp = group->GM_bigtk;
+ group->GM_bigtk = group->GN_bigtk;
+ group->GN_bigtk = tmp;
+ }
wpa_gtk_update(wpa_auth, group);
wpa_group_config_group_keys(wpa_auth, group);
}
@@ -5689,28 +5933,11 @@
int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
const u8 *pmk, size_t pmk_len, const u8 *pmkid,
- int session_timeout, int akmp)
-{
- if (!wpa_auth || wpa_auth->conf.disable_pmksa_caching)
- return -1;
-
- wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK (2)", pmk, PMK_LEN);
- if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid,
- NULL, 0, wpa_auth->addr, addr, session_timeout,
- NULL, akmp))
- return 0;
-
- return -1;
-}
-
-
-int wpa_auth_pmksa_add3(struct wpa_authenticator *wpa_auth, const u8 *addr,
- const u8 *pmk, size_t pmk_len, const u8 *pmkid,
int session_timeout, int akmp, const u8 *dpp_pkhash)
{
struct rsn_pmksa_cache_entry *entry;
- if (wpa_auth->conf.disable_pmksa_caching)
+ if (!wpa_auth || wpa_auth->conf.disable_pmksa_caching)
return -1;
wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK (3)", pmk, PMK_LEN);
@@ -5834,13 +6061,14 @@
void wpa_auth_pmksa_set_to_sm(struct rsn_pmksa_cache_entry *pmksa,
struct wpa_state_machine *sm,
struct wpa_authenticator *wpa_auth,
- u8 *pmkid, u8 *pmk)
+ u8 *pmkid, u8 *pmk, size_t *pmk_len)
{
if (!sm)
return;
sm->pmksa = pmksa;
- os_memcpy(pmk, pmksa->pmk, PMK_LEN);
+ os_memcpy(pmk, pmksa->pmk, pmksa->pmk_len);
+ *pmk_len = pmksa->pmk_len;
os_memcpy(pmkid, pmksa->pmkid, PMKID_LEN);
os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmksa->pmkid, PMKID_LEN);
}
@@ -6358,7 +6586,7 @@
size_t elen;
elen = pos - kde;
- res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name);
+ res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name, true);
if (res < 0) {
wpa_printf(MSG_ERROR,
"FT: Failed to insert PMKR1Name into RSN IE in EAPOL-Key data");