mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(wifi): Refactor and update wpa_supplicant with upstream
This commit is contained in:
parent
1685dbc985
commit
e746fc0deb
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 "
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user