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 c2255e1119..3d46f7fe12 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_wpas_glue.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c index 4f1da5d792..9a74c4e6b7 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c @@ -93,7 +93,7 @@ int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, } -void wpa_supplicant_transition_disable(void *sm, u8 bitmap) +void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap) { wpa_printf(MSG_DEBUG, "TRANSITION_DISABLE %02x", bitmap); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h index 11f5b3ddff..e18ad28cdd 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h @@ -31,7 +31,7 @@ void wpa_free_eapol(u8 *buffer); int wpa_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *data, size_t data_len); -void wpa_supplicant_transition_disable(void *sm, u8 bitmap); +void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap); int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, const u8 *data, size_t data_len); diff --git a/components/wpa_supplicant/src/common/sae.c b/components/wpa_supplicant/src/common/sae.c index e97f99d449..bc394c80db 100644 --- a/components/wpa_supplicant/src/common/sae.c +++ b/components/wpa_supplicant/src/common/sae.c @@ -170,7 +170,7 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, return ESP_FAIL; res = dragonfly_is_quadratic_residue_blind(sae->tmp->ec, qr, qnr, - y_sqr); + y_sqr); crypto_bignum_deinit(y_sqr, 1); if (res < 0) { @@ -219,7 +219,6 @@ static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed, res = -1; a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len); - if (!a) goto fail; @@ -240,10 +239,9 @@ static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed, if (b == NULL || crypto_bignum_sub(sae->tmp->prime, b, b) < 0 || crypto_bignum_div(b, sae->tmp->order, b) < 0) - goto fail; + goto fail; } - if (!b) goto fail; @@ -314,7 +312,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); @@ -432,6 +430,7 @@ fail: crypto_bignum_deinit(x, 1); os_memset(x_bin, 0, sizeof(x_bin)); os_memset(x_cand_bin, 0, sizeof(x_cand_bin)); + return res; } @@ -450,6 +449,7 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1, struct crypto_bignum *pwe; size_t prime_len = sae->tmp->prime_len * 8; u8 *pwe_buf; + crypto_bignum_deinit(sae->tmp->pwe_ffc, 1); sae->tmp->pwe_ffc = NULL; @@ -478,7 +478,7 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1, k = dragonfly_min_pwe_loop_iter(sae->group); for (counter = 1; counter <= k || !found; counter++) { - u8 pwd_seed[SHA256_MAC_LEN]; + u8 pwd_seed[SHA256_MAC_LEN]; int res; if (counter > 200) { @@ -570,6 +570,7 @@ static void debug_print_bignum(const char *title, const struct crypto_bignum *a, bin_clear_free(bin, prime_len); } + static struct crypto_ec_point * sswu(struct crypto_ec *ec, int group, const struct crypto_bignum *u) { @@ -1480,9 +1481,9 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) * KCK || PMK = KDF-Hash-Length(keyseed, "SAE KCK and PMK", * (commit-scalar + peer-commit-scalar) modulo r) * PMKID = L((commit-scalar + peer-commit-scalar) modulo r, 0, 128) - * - * When SAE_PK is used, - * KCK || PMK || KEK = KDF-Hash-Length(keyseed, "SAE-PK keys", context) + * + * When SAE-PK is used, + * KCK || PMK || KEK = KDF-Hash-Length(keyseed, "SAE-PK keys", context) */ if (!sae->h2e) hash_len = SHA256_MAC_LEN; @@ -1542,7 +1543,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); @@ -1550,13 +1551,13 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k) #ifdef CONFIG_SAE_PK if (sae->pk) { if (sae_kdf_hash(hash_len, keyseed, "SAE-PK keys", - val, sae->tmp->order_len, - keys, 2 * hash_len + SAE_PMK_LEN) < 0) + val, sae->tmp->order_len, + keys, 2 * hash_len + SAE_PMK_LEN) < 0) goto fail; } else { if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK", - val, sae->tmp->order_len, - keys, hash_len + SAE_PMK_LEN) < 0) + val, sae->tmp->order_len, + keys, hash_len + SAE_PMK_LEN) < 0) goto fail; } #else /* CONFIG_SAE_PK */ @@ -1568,20 +1569,22 @@ 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); #ifdef CONFIG_SAE_PK if (sae->pk) { - os_memcpy(sae->tmp->kek, keys + hash_len + SAE_PMK_LEN, hash_len); + os_memcpy(sae->tmp->kek, keys + hash_len + SAE_PMK_LEN, + hash_len); sae->tmp->kek_len = hash_len; wpa_hexdump_key(MSG_DEBUG, "SAE: KEK for SAE-PK", - sae->tmp->kek, sae->tmp->kek_len); + sae->tmp->kek, sae->tmp->kek_len); } #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; @@ -1658,6 +1661,7 @@ int sae_write_commit(struct sae_data *sae, struct wpabuf *buf, wpa_printf(MSG_DEBUG, "SAE: own Password Identifier: %s", identifier); } + if (sae->h2e && sae->tmp->own_rejected_groups) { wpa_hexdump_buf(MSG_DEBUG, "SAE: own Rejected Groups", sae->tmp->own_rejected_groups); @@ -1725,7 +1729,7 @@ u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group) static int sae_is_password_id_elem(const u8 *pos, const u8 *end) { - return end - pos >= 3 && + return end - pos >= 3 && pos[0] == WLAN_EID_EXTENSION && pos[1] >= 1 && end - pos - 2 >= pos[1] && @@ -1842,6 +1846,7 @@ static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos, return WLAN_STATUS_UNSPECIFIED_FAILURE; } + crypto_bignum_deinit(sae->peer_commit_scalar, 0); sae->peer_commit_scalar = peer_scalar; wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar", @@ -2144,7 +2149,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->tmp->kck_len, sae->tmp->kck, sae->tmp->kck_len, 5, addr, len, confirm); } @@ -2171,7 +2176,7 @@ static int sae_cn_confirm_ecc(struct sae_data *sae, const u8 *sc, } sae_cn_confirm(sae, sc, scalar1, element_b1, 2 * sae->tmp->prime_len, - scalar2, element_b2, 2 * sae->tmp->prime_len, confirm); + scalar2, element_b2, 2 * sae->tmp->prime_len, confirm); return ESP_OK; } @@ -2187,7 +2192,7 @@ static int sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc, u8 element_b2[SAE_MAX_PRIME_LEN]; if (crypto_bignum_to_bin(element1, element_b1, sizeof(element_b1), - sae->tmp->prime_len) < 0) { + sae->tmp->prime_len) < 0) { wpa_printf(MSG_ERROR, "SAE: failed bignum op while generating SAE confirm - e1"); return ESP_FAIL; } @@ -2207,10 +2212,13 @@ 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 +2230,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 +2239,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 +2251,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) 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; @@ -2298,13 +2307,14 @@ int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len) #ifdef CONFIG_SAE_PK if (sae_check_confirm_pk(sae, data + 2 + hash_len, - len - 2 - hash_len) != ESP_OK) + len - 2 - hash_len) != ESP_OK) return ESP_FAIL; #endif /* CONFIG_SAE_PK */ return ESP_OK; } + const char * sae_state_txt(enum sae_state state) { switch (state) { diff --git a/components/wpa_supplicant/src/common/sae.h b/components/wpa_supplicant/src/common/sae.h index 77a834cdcd..0f266bc1c2 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; @@ -109,15 +110,14 @@ struct sae_data { u16 send_confirm; u8 pmk[SAE_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; + struct sae_temporary_data *tmp; }; int sae_set_group(struct sae_data *sae, int group); diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 05e00463aa..cbf1fa630f 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; @@ -835,10 +847,9 @@ 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_OWE || + wpa_key_mgmt_sae(akmp) || + wpa_key_mgmt_suite_b(akmp); } int wpa_use_aes_key_wrap(int akmp) @@ -936,6 +947,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 +1139,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,25 +1161,25 @@ 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), + if (wpa_key_mgmt_sha256(akmp)) { + 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); - + } else { + 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 4462c81f00..1f9adb76a2 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -395,7 +395,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data); 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); @@ -447,7 +447,7 @@ 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); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index e581538990..d23da66d29 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,23 @@ 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 +598,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, @@ -1205,7 +1217,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, @@ -1574,7 +1586,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, @@ -1683,7 +1695,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) { @@ -1754,10 +1766,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 " @@ -1860,7 +1869,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) { @@ -1924,20 +1933,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)", @@ -1948,20 +1951,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 && @@ -1982,7 +1980,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 " 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;