From 0dbd2aa24c6c3d7fc3c91f44383e29b7a25326bc Mon Sep 17 00:00:00 2001 From: Sajia Date: Fri, 30 Aug 2024 18:33:31 +0530 Subject: [PATCH] fix(esp_wifi): Refactor and update wpa_supplicant with upstream --- .../esp_supplicant/src/esp_eap_client.c | 2 +- .../esp_supplicant/src/esp_wpa3.c | 2 +- components/wpa_supplicant/src/common/defs.h | 1 + components/wpa_supplicant/src/common/sae.c | 22 +++-- components/wpa_supplicant/src/common/sae.h | 6 +- .../wpa_supplicant/src/common/wpa_common.c | 98 ++++++++++++++----- .../wpa_supplicant/src/common/wpa_common.h | 5 +- components/wpa_supplicant/src/rsn_supp/wpa.c | 63 ++++++------ components/wpa_supplicant/src/rsn_supp/wpa.h | 2 +- .../wpa_supplicant/src/rsn_supp/wpa_ie.c | 29 +++--- 10 files changed, 143 insertions(+), 87 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c index 12701161de..ba30370e7c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -590,7 +590,7 @@ static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bss break; case EAP_CODE_SUCCESS: if (sm->eapKeyData) { - wpa_set_pmk(sm->eapKeyData, NULL, false); + wpa_set_pmk(sm->eapKeyData, 0, NULL, false); os_free(sm->eapKeyData); sm->eapKeyData = NULL; wpa_printf(MSG_INFO, ">>>>>EAP FINISH"); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index c5a6ccbb06..9f849af4b3 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -296,7 +296,7 @@ static int wpa3_parse_sae_confirm(u8 *buf, u32 len) } g_sae_data.state = SAE_ACCEPTED; - wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmkid, true); + wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmk_len, g_sae_data.pmkid, true); return ESP_OK; } diff --git a/components/wpa_supplicant/src/common/defs.h b/components/wpa_supplicant/src/common/defs.h index 6799370dec..26c8d5f17b 100644 --- a/components/wpa_supplicant/src/common/defs.h +++ b/components/wpa_supplicant/src/common/defs.h @@ -48,6 +48,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean; #define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16) #define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17) #define WPA_KEY_MGMT_OWE BIT(22) +#define WPA_KEY_MGMT_DPP BIT(23) static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) { diff --git a/components/wpa_supplicant/src/common/sae.c b/components/wpa_supplicant/src/common/sae.c index e97f99d449..a23647ca41 100644 --- a/components/wpa_supplicant/src/common/sae.c +++ b/components/wpa_supplicant/src/common/sae.c @@ -314,7 +314,7 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, if (dragonfly_get_random_qr_qnr(sae->tmp->prime, &qr, &qnr) < 0 || crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 || crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0) - goto fail; + goto fail; wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password", password, password_len); @@ -1542,7 +1542,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) * zero padding it from left to the length of the order (in full * octets). */ if (crypto_bignum_to_bin(tmp, val, sizeof(val), - sae->tmp->order_len) < 0) { + sae->tmp->order_len) < 0) { goto fail; } wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN); @@ -1568,6 +1568,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) forced_memzero(keyseed, sizeof(keyseed)); os_memcpy(sae->tmp->kck, keys, hash_len); + sae->tmp->kck_len = hash_len; os_memcpy(sae->pmk, keys + hash_len, SAE_PMK_LEN); os_memcpy(sae->pmkid, val, SAE_PMKID_LEN); @@ -1581,7 +1582,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) #endif /* CONFIG_SAE_PK */ forced_memzero(keys, sizeof(keys)); wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", - sae->tmp->kck, SAE_KCK_LEN); + sae->tmp->kck, sae->tmp->kck_len); wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN); ret = 0; @@ -2144,7 +2145,7 @@ static int sae_cn_confirm(struct sae_data *sae, const u8 *sc, len[3] = sae->tmp->prime_len; addr[4] = element2; len[4] = element2_len; - return hkdf_extract(SAE_KCK_LEN, sae->tmp->kck, SAE_KCK_LEN, + return hkdf_extract(SAE_KCK_LEN, sae->tmp->kck, sae->tmp->kck_len, 5, addr, len, confirm); } @@ -2207,10 +2208,12 @@ static int sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc, int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf) { const u8 *sc; + size_t hash_len; if (sae->tmp == NULL) return ESP_FAIL; + hash_len = sae->tmp->kck_len; /* Send-Confirm */ sc = wpabuf_put(buf, 0); wpabuf_put_le16(buf, sae->send_confirm); @@ -2222,7 +2225,7 @@ int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf) sae->tmp->own_commit_element_ecc, sae->peer_commit_scalar, sae->tmp->peer_commit_element_ecc, - wpabuf_put(buf, SHA256_MAC_LEN))) { + wpabuf_put(buf, hash_len))) { wpa_printf(MSG_ERROR, "SAE: failed generate SAE confirm (ecc)"); return ESP_FAIL; } @@ -2231,7 +2234,7 @@ int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf) sae->tmp->own_commit_element_ffc, sae->peer_commit_scalar, sae->tmp->peer_commit_element_ffc, - wpabuf_put(buf, SHA256_MAC_LEN))) { + wpabuf_put(buf, hash_len))) { wpa_printf(MSG_ERROR, "SAE: failed generate SAE confirm (ffc)"); return ESP_FAIL; } @@ -2243,11 +2246,12 @@ int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf) int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len) { u8 verifier[SAE_MAX_HASH_LEN]; - size_t hash_len= SAE_KCK_LEN; + size_t hash_len; - if (!sae->tmp) + if (!sae->tmp) { return ESP_FAIL; - + } + hash_len = sae->tmp->kck_len; if (len < 2 + hash_len) { wpa_printf(MSG_DEBUG, "SAE: Too short confirm message"); return ESP_FAIL; diff --git a/components/wpa_supplicant/src/common/sae.h b/components/wpa_supplicant/src/common/sae.h index 77a834cdcd..5d2086b0c2 100644 --- a/components/wpa_supplicant/src/common/sae.h +++ b/components/wpa_supplicant/src/common/sae.h @@ -42,7 +42,8 @@ struct sae_pk { }; struct sae_temporary_data { - u8 kck[SAE_KCK_LEN]; + u8 kck[SAE_MAX_HASH_LEN]; + size_t kck_len; struct crypto_bignum *own_commit_scalar; struct crypto_bignum *own_commit_element_ffc; struct crypto_ec_point *own_commit_element_ecc; @@ -108,14 +109,15 @@ struct sae_data { enum sae_state state; u16 send_confirm; u8 pmk[SAE_PMK_LEN]; + size_t pmk_len; u8 pmkid[SAE_PMKID_LEN]; struct crypto_bignum *peer_commit_scalar; + struct crypto_bignum *peer_commit_scalar_accepted; int group; unsigned int sync; /* protocol instance variable: Sync */ u16 rc; /* protocol instance variable: Rc (received send-confirm) */ struct sae_temporary_data *tmp; - struct crypto_bignum *peer_commit_scalar_accepted; unsigned int h2e:1; unsigned int pk:1; }; diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 8cfc1fec83..9a0a0d1fe9 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -235,27 +235,39 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, #endif /* CONFIG_IEEE80211R */ -static unsigned int wpa_kck_len(int akmp) +static unsigned int wpa_kck_len(int akmp, size_t pmk_len) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return 24; - return 16; + case WPA_KEY_MGMT_OWE: + return pmk_len / 2; + default: + return 16; + } } -static unsigned int wpa_kek_len(int akmp) +static unsigned int wpa_kek_len(int akmp, size_t pmk_len) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return 32; - return 16; + case WPA_KEY_MGMT_OWE: + return pmk_len <= 32 ? 16 : 32; + default: + return 16; + } } -unsigned int wpa_mic_len(int akmp) +unsigned int wpa_mic_len(int akmp, size_t pmk_len) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return 24; - - return 16; + default: + return 16; + } } static int rsn_selector_to_bitfield(const u8 *s) @@ -783,8 +795,8 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, os_memcpy(pos, sta_addr, ETH_ALEN); pos += ETH_ALEN; - ptk->kck_len = wpa_kck_len(akmp); - ptk->kek_len = wpa_kek_len(akmp); + ptk->kck_len = wpa_kck_len(akmp, PMK_LEN); + ptk->kek_len = wpa_kek_len(akmp, PMK_LEN); ptk->tk_len = wpa_cipher_key_len(cipher); ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len; @@ -826,8 +838,6 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, #endif /* CONFIG_IEEE80211R */ - - /** * wpa_use_akm_defined - Is AKM-defined Key Descriptor Version used * @akmp: WPA_KEY_MGMT_* used in key derivation @@ -835,15 +845,27 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, */ int wpa_use_akm_defined(int akmp){ - int ret = 0; - if(wpa_key_mgmt_sae(akmp)) - ret = 1; - return ret; + return akmp == WPA_KEY_MGMT_OSEN || + akmp == WPA_KEY_MGMT_OWE || + akmp == WPA_KEY_MGMT_DPP || + wpa_key_mgmt_sae(akmp) || + wpa_key_mgmt_suite_b(akmp); } +/** + * wpa_use_aes_key_wrap - Is AES Keywrap algorithm used for EAPOL-Key Key Data + * @akmp: WPA_KEY_MGMT_* used in key derivation + * Returns: 1 if AES Keywrap is used; 0 otherwise + * + * Note: AKM 00-0F-AC:1 and 00-0F-AC:2 have special rules for selecting whether + * to use AES Keywrap based on the negotiated pairwise cipher. This function + * does not cover those special cases. + */ int wpa_use_aes_key_wrap(int akmp) { return akmp == WPA_KEY_MGMT_OSEN || + akmp == WPA_KEY_MGMT_OWE || + akmp == WPA_KEY_MGMT_DPP || wpa_key_mgmt_ft(akmp) || wpa_key_mgmt_sha256(akmp) || wpa_key_mgmt_sae(akmp) || @@ -936,6 +958,35 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver, return 0; } +u32 wpa_akm_to_suite(int akm) +{ +#ifdef CONFIG_IEEE80211R + if (akm & WPA_KEY_MGMT_FT_IEEE8021X) + return RSN_AUTH_KEY_MGMT_FT_802_1X; + if (akm & WPA_KEY_MGMT_FT_PSK) + return RSN_AUTH_KEY_MGMT_FT_PSK; +#endif /* CONFIG_IEEE80211R */ + if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256) + return RSN_AUTH_KEY_MGMT_802_1X_SHA256; + if (akm & WPA_KEY_MGMT_IEEE8021X) + return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; + if (akm & WPA_KEY_MGMT_PSK_SHA256) + return RSN_AUTH_KEY_MGMT_PSK_SHA256; + if (akm & WPA_KEY_MGMT_PSK) + return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X; + if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B) + return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B; + if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192; + if (akm & WPA_KEY_MGMT_SAE) + return RSN_AUTH_KEY_MGMT_SAE; + if (akm & WPA_KEY_MGMT_FT_SAE) + return RSN_AUTH_KEY_MGMT_FT_SAE; + if (akm & WPA_KEY_MGMT_OWE) + return RSN_AUTH_KEY_MGMT_OWE; + return 0; +} + int wpa_compare_rsn_ie(int ft_initial_assoc, const u8 *ie1, size_t ie1len, const u8 *ie2, size_t ie2len) @@ -1099,6 +1150,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, return -1; } u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN]; + size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN; u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN]; size_t ptk_len; @@ -1120,24 +1172,24 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, WPA_NONCE_LEN); } - ptk->kck_len = wpa_kck_len(akmp); - ptk->kek_len = wpa_kek_len(akmp); + ptk->kck_len = wpa_kck_len(akmp, pmk_len); + ptk->kek_len = wpa_kek_len(akmp, pmk_len); ptk->tk_len = wpa_cipher_key_len(cipher); ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len; #if defined(CONFIG_SUITEB192) if (wpa_key_mgmt_sha384(akmp)) { wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)"); - if (sha384_prf(pmk, pmk_len, label, data, sizeof(data), + if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len) < 0) return -1; } else #endif if (wpa_key_mgmt_sha256(akmp)) - sha256_prf(pmk, pmk_len, label, data, sizeof(data), + sha256_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len); else - sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp, ptk_len); + sha1_prf(pmk, pmk_len, label, data, data_len, tmp, ptk_len); wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR"\n", MAC2STR(addr1), MAC2STR(addr2)); diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 92f5c140d7..23c7e58a49 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -399,6 +399,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, int wpa_parse_wpa_ie_rsnxe(const u8 *rsnxe_ie, size_t rsnxe_ie_len, struct wpa_ie_data *data); +u32 wpa_akm_to_suite(int akm); int wpa_compare_rsn_ie(int ft_initial_assoc, const u8 *ie1, size_t ie1len, const u8 *ie2, size_t ie2len); @@ -450,7 +451,9 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data); int rsn_cipher_put_suites(u8 *pos, int ciphers); -unsigned int wpa_mic_len(int akmp); +unsigned int wpa_mic_len(int akmp, size_t pmk_len); +int wpa_use_akm_defined(int akmp); +int wpa_use_aes_key_wrap(int akmp); int wpa_use_akm_defined(int akmp); int wpa_use_aes_key_wrap(int akmp); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index e4c26f8c23..ee4c584cc9 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -260,7 +260,7 @@ void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, size_t kck_len, goto out; } wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, kck_len); - wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, wpa_mic_len(sm->key_mgmt)); + wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, wpa_mic_len(sm->key_mgmt, sm->pmk_len)); wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len); wpa_sm_ether_send(sm, dest, proto, msg, msg_len); out: @@ -302,7 +302,7 @@ static void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise) return; } - mic_len = wpa_mic_len(sm->key_mgmt); + mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, hdrlen, &rlen, (void *) &reply); @@ -424,11 +424,24 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, //eapol_sm_notify_cached(sm->eapol); #ifdef CONFIG_IEEE80211R sm->xxkey_len = 0; +#ifdef CONFIG_WPA3_SAE + if ((sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) && + sm->pmk_len == PMK_LEN) { + /* Need to allow FT key derivation to proceed with + * PMK from SAE being used as the XXKey in cases where + * the PMKID in msg 1/4 matches the PMKSA entry that was + * just added based on SAE authentication for the + * initial mobility domain association. */ + os_memcpy(sm->xxkey, sm->pmk, sm->pmk_len); + sm->xxkey_len = sm->pmk_len; + } +#endif /* CONFIG_WPA3_SAE */ + #endif /* CONFIG_IEEE80211R */ } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) { int res = 0, pmk_len; /* For ESP_SUPPLICANT this is already set using wpa_set_pmk*/ - //res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN); + //res = eapol_sm_get_key(sm->eapol, 0, sm->pmk, PMK_LEN); if (wpa_key_mgmt_sha384(sm->key_mgmt)) pmk_len = PMK_LEN_SUITE_B_192; else @@ -586,7 +599,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, #endif /* CONFIG_IEEE80211R */ wpa_hexdump(MSG_MSGDUMP, "WPA: WPA IE for msg 2/4\n", wpa_ie, wpa_ie_len); - mic_len = wpa_mic_len(sm->key_mgmt); + mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, hdrlen + wpa_ie_len, @@ -1208,7 +1221,7 @@ static int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *ds struct wpa_eapol_key_192 *reply192; u8 *rbuf, *key_mic; - mic_len = wpa_mic_len(sm->key_mgmt); + mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, @@ -1577,7 +1590,7 @@ static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm, struct wpa_eapol_key_192 *reply192; u8 *rbuf, *key_mic; - mic_len = wpa_mic_len(sm->key_mgmt); + mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply); rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL, @@ -1686,7 +1699,7 @@ static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm, { u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; int ok = 0; - size_t mic_len = wpa_mic_len(sm->key_mgmt); + size_t mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); os_memcpy(mic, key->key_mic, mic_len); if (sm->tptk_set) { @@ -1757,10 +1770,7 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm, } } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || ver == WPA_KEY_INFO_TYPE_AES_128_CMAC || - sm->key_mgmt == WPA_KEY_MGMT_OSEN || - wpa_key_mgmt_suite_b(sm->key_mgmt) || - sm->key_mgmt == WPA_KEY_MGMT_SAE || - sm->key_mgmt == WPA_KEY_MGMT_OWE) { + wpa_use_aes_key_wrap(sm->key_mgmt)) { u8 *buf; if (*key_data_len < 8 || *key_data_len % 8) { wpa_printf(MSG_DEBUG, "WPA: Unsupported " @@ -1863,7 +1873,7 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) size_t mic_len, keyhdrlen; u8 *key_data; - mic_len = wpa_mic_len(sm->key_mgmt); + mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len); keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key); if (len < sizeof(*hdr) + keyhdrlen) { @@ -1927,20 +1937,14 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && #ifdef CONFIG_IEEE80211W ver != WPA_KEY_INFO_TYPE_AES_128_CMAC && -#ifdef CONFIG_WPA3_SAE - sm->key_mgmt != WPA_KEY_MGMT_SAE && #endif - !wpa_key_mgmt_suite_b(sm->key_mgmt) && -#ifdef CONFIG_OWE_STA - sm->key_mgmt != WPA_KEY_MGMT_OWE && -#endif /* CONFIG_OWE_STA */ -#endif - ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { + ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES && + !wpa_use_akm_defined(sm->key_mgmt)) { wpa_printf(MSG_DEBUG, "WPA: Unsupported EAPOL-Key descriptor " "version %d.", ver); goto out; } - if (wpa_key_mgmt_suite_b(sm->key_mgmt) && + if (wpa_use_akm_defined(sm->key_mgmt) && ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) { wpa_msg(NULL, MSG_INFO, "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)", @@ -1951,20 +1955,15 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) #ifdef CONFIG_IEEE80211W if (wpa_key_mgmt_sha256(sm->key_mgmt)) { if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC && - sm->key_mgmt != WPA_KEY_MGMT_OSEN && - !wpa_key_mgmt_suite_b(sm->key_mgmt) && - sm->key_mgmt != WPA_KEY_MGMT_SAE && - sm->key_mgmt != WPA_KEY_MGMT_OWE) { + !wpa_use_akm_defined(sm->key_mgmt)) { goto out; } } else #endif if (sm->pairwise_cipher == WPA_CIPHER_CCMP && - !wpa_key_mgmt_suite_b(sm->key_mgmt) && - ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES && - sm->key_mgmt != WPA_KEY_MGMT_SAE && - sm->key_mgmt != WPA_KEY_MGMT_OWE) { + !wpa_use_akm_defined(sm->key_mgmt) && + ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { wpa_printf(MSG_DEBUG, "WPA: CCMP is used, but EAPOL-Key " "descriptor version (%d) is not 2.", ver); if (sm->group_cipher != WPA_CIPHER_CCMP && @@ -1985,7 +1984,7 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) #ifdef CONFIG_GCMP if (sm->pairwise_cipher == WPA_CIPHER_GCMP && - !wpa_key_mgmt_suite_b(sm->key_mgmt) && + !wpa_use_akm_defined(sm->key_mgmt) && ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { wpa_msg(NULL, MSG_INFO, "WPA: GCMP is used, but EAPOL-Key " @@ -2308,13 +2307,15 @@ void wpa_set_profile(u32 wpa_proto, u8 auth_mode) } } -void wpa_set_pmk(uint8_t *pmk, const u8 *pmkid, bool cache_pmksa) +void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pmksa) { struct wpa_sm *sm = &gWpaSm; int pmk_len; if (wpa_key_mgmt_sha384(sm->key_mgmt)) pmk_len = PMK_LEN_SUITE_B_192; + else if (wpa_key_mgmt_sae(sm->key_mgmt)) + pmk_len = pmk_length; else pmk_len = PMK_LEN; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.h b/components/wpa_supplicant/src/rsn_supp/wpa.h index 4f7a768fc6..257735d270 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa.h @@ -38,7 +38,7 @@ struct l2_ethhdr { void wpa_sm_set_state(enum wpa_states state); -void wpa_set_pmk(uint8_t *pmk, const u8 *pmkid, bool cache_pmksa); +void wpa_set_pmk(uint8_t *pmk, size_t pmk_length, const u8 *pmkid, bool cache_pmksa); int wpa_michael_mic_failure(u16 isunicast); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c index 12b40ba6c6..2fc2307d71 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_ie.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa_ie.c @@ -51,6 +51,7 @@ static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len, { u8 *pos; struct wpa_ie_hdr *hdr; + u32 suite; if (wpa_ie_len < sizeof(*hdr) + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN + 2 + WPA_SELECTOR_LEN) @@ -62,34 +63,26 @@ static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len, WPA_PUT_LE16(hdr->version, WPA_VERSION); pos = (u8 *) (hdr + 1); - if (group_cipher == WPA_CIPHER_CCMP) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); - } else if (group_cipher == WPA_CIPHER_TKIP) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); - } else if (group_cipher == WPA_CIPHER_WEP104) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP104); - } else if (group_cipher == WPA_CIPHER_WEP40) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_WEP40); - } else { - wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", + suite = wpa_cipher_to_suite(WPA_PROTO_WPA, group_cipher); + if (suite == 0) { + wpa_printf(MSG_WARNING, "Invalid group cipher (%d).", group_cipher); return -1; } + RSN_SELECTOR_PUT(pos, suite); pos += WPA_SELECTOR_LEN; *pos++ = 1; *pos++ = 0; - if (pairwise_cipher == WPA_CIPHER_CCMP) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP); - } else if (pairwise_cipher == WPA_CIPHER_TKIP) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP); - } else if (pairwise_cipher == WPA_CIPHER_NONE) { - RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE); - } else { - wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", + suite = wpa_cipher_to_suite(WPA_PROTO_WPA, pairwise_cipher); + if (suite == 0 || + (!wpa_cipher_valid_pairwise(pairwise_cipher) && + pairwise_cipher != WPA_CIPHER_NONE)) { + wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).", pairwise_cipher); return -1; } + RSN_SELECTOR_PUT(pos, suite); pos += WPA_SELECTOR_LEN; *pos++ = 1;