feat(wifi): Refactor and update wpa_supplicant with upstream

This commit is contained in:
Shreyas Sheth 2023-10-09 09:26:32 +05:30
parent 1685dbc985
commit e746fc0deb
9 changed files with 148 additions and 106 deletions

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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 "

View File

@ -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;