struct wpa_ft_ies parse;
u8 *ric_start;
u8 *anonce, *snonce;
+ const u8 *kck;
+ size_t kck_len;
if (sm == NULL)
return pos;
if (ric_start == pos)
ric_start = NULL;
+ if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
+ kck = sm->PTK.kck2;
+ kck_len = sm->PTK.kck2_len;
+ } else {
+ kck = sm->PTK.kck;
+ kck_len = sm->PTK.kck_len;
+ }
if (auth_alg == WLAN_AUTH_FT &&
- wpa_ft_mic(sm->PTK.kck, sm->PTK.kck_len, sm->addr,
- sm->wpa_auth->addr, 6,
+ wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 6,
mdie, mdie_len, ftie, ftie_len,
rsnie, rsnie_len,
ric_start, ric_start ? pos - ric_start : 0,
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
size_t mic_len = 16;
unsigned int count;
+ const u8 *kck;
+ size_t kck_len;
if (sm == NULL)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
- if (wpa_ft_mic(sm->PTK.kck, sm->PTK.kck_len, sm->addr,
- sm->wpa_auth->addr, 5,
+ if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
+ kck = sm->PTK.kck2;
+ kck_len = sm->PTK.kck2_len;
+ } else {
+ kck = sm->PTK.kck;
+ kck_len = sm->PTK.kck_len;
+ }
+ if (wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 5,
parse.mdie - 2, parse.mdie_len + 2,
parse.ftie - 2, parse.ftie_len + 2,
parse.rsn - 2, parse.rsn_len + 2,
}
+#ifdef CONFIG_IEEE80211R
+static unsigned int wpa_kck2_len(int akmp)
+{
+ switch (akmp) {
+ case WPA_KEY_MGMT_FT_FILS_SHA256:
+ return 16;
+ case WPA_KEY_MGMT_FT_FILS_SHA384:
+ return 24;
+ default:
+ return 0;
+ }
+}
+#endif /* CONFIG_IEEE80211R */
+
+
static unsigned int wpa_kek_len(int akmp, size_t pmk_len)
{
switch (akmp) {
}
+#ifdef CONFIG_IEEE80211R
+static unsigned int wpa_kek2_len(int akmp)
+{
+ switch (akmp) {
+ case WPA_KEY_MGMT_FT_FILS_SHA256:
+ return 16;
+ case WPA_KEY_MGMT_FT_FILS_SHA384:
+ return 32;
+ default:
+ return 0;
+ }
+}
+#endif /* CONFIG_IEEE80211R */
+
+
unsigned int wpa_mic_len(int akmp, size_t pmk_len)
{
switch (akmp) {
os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
+ ptk->kek2_len = 0;
+ ptk->kck2_len = 0;
+
os_memset(tmp, 0, sizeof(tmp));
return 0;
}
fils_ft, *fils_ft_len);
}
+ ptk->kek2_len = 0;
+ ptk->kck2_len = 0;
+
os_memset(tmp, 0, sizeof(tmp));
ret = 0;
err:
u8 *pos, hash[32];
const u8 *addr[6];
size_t len[6];
- u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
- size_t ptk_len;
+ u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+ size_t ptk_len, offset;
/*
* PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
pos += ETH_ALEN;
ptk->kck_len = wpa_kck_len(akmp, PMK_LEN);
+ ptk->kck2_len = wpa_kck2_len(akmp);
ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
+ ptk->kek2_len = wpa_kek2_len(akmp);
ptk->tk_len = wpa_cipher_key_len(cipher);
- ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
+ ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
+ ptk->kck2_len + ptk->kek2_len;
if (sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf,
tmp, ptk_len) < 0)
os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
os_memcpy(ptk->kck, tmp, ptk->kck_len);
- os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
- os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
+ offset = ptk->kck_len;
+ os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
+ offset += ptk->kek_len;
+ os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
+ offset += ptk->tk_len;
+ os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
+ offset = ptk->kck2_len;
+ os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
+ if (ptk->kck2_len)
+ wpa_hexdump_key(MSG_DEBUG, "FT: KCK2",
+ ptk->kck2, ptk->kck2_len);
+ if (ptk->kek2_len)
+ wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
+ ptk->kek2, ptk->kek2_len);
wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
u8 ptk_name[WPA_PMK_NAME_LEN];
int ret;
const u8 *bssid;
+ const u8 *kck;
+ size_t kck_len;
wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len);
ptk_name, sm->key_mgmt, sm->pairwise_cipher) < 0)
return -1;
+ if (wpa_key_mgmt_fils(sm->key_mgmt)) {
+ kck = sm->ptk.kck2;
+ kck_len = sm->ptk.kck2_len;
+ } else {
+ kck = sm->ptk.kck;
+ kck_len = sm->ptk.kck_len;
+ }
ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, ftie->anonce,
sm->pmk_r1_name,
- sm->ptk.kck, sm->ptk.kck_len, bssid,
+ kck, kck_len, bssid,
ric_ies, ric_ies_len,
parse.mdie ? parse.mdie - 2 : NULL);
if (ft_ies) {
struct rsn_ftie *ftie;
unsigned int count;
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
+ const u8 *kck;
+ size_t kck_len;
wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
return -1;
}
- if (wpa_ft_mic(sm->ptk.kck, sm->ptk.kck_len, sm->own_addr, src_addr, 6,
+ if (wpa_key_mgmt_fils(sm->key_mgmt)) {
+ kck = sm->ptk.kck2;
+ kck_len = sm->ptk.kck2_len;
+ } else {
+ kck = sm->ptk.kck;
+ kck_len = sm->ptk.kck_len;
+ }
+
+ if (wpa_ft_mic(kck, kck_len, sm->own_addr, src_addr, 6,
parse.mdie - 2, parse.mdie_len + 2,
parse.ftie - 2, parse.ftie_len + 2,
parse.rsn - 2, parse.rsn_len + 2,