|
@@ -1918,7 +1918,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2)
|
|
static int ieee80211w_kde_len(struct wpa_state_machine *sm)
|
|
static int ieee80211w_kde_len(struct wpa_state_machine *sm)
|
|
{
|
|
{
|
|
if (sm->mgmt_frame_prot) {
|
|
if (sm->mgmt_frame_prot) {
|
|
- return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde);
|
|
|
|
|
|
+ size_t len;
|
|
|
|
+ len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
|
|
|
|
+ return 2 + RSN_SELECTOR_LEN + WPA_IGTK_KDE_PREFIX_LEN + len;
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -1930,6 +1932,7 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
|
|
struct wpa_igtk_kde igtk;
|
|
struct wpa_igtk_kde igtk;
|
|
struct wpa_group *gsm = sm->group;
|
|
struct wpa_group *gsm = sm->group;
|
|
u8 rsc[WPA_KEY_RSC_LEN];
|
|
u8 rsc[WPA_KEY_RSC_LEN];
|
|
|
|
+ size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
|
|
|
|
|
|
if (!sm->mgmt_frame_prot)
|
|
if (!sm->mgmt_frame_prot)
|
|
return pos;
|
|
return pos;
|
|
@@ -1941,17 +1944,18 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
|
|
os_memset(igtk.pn, 0, sizeof(igtk.pn));
|
|
os_memset(igtk.pn, 0, sizeof(igtk.pn));
|
|
else
|
|
else
|
|
os_memcpy(igtk.pn, rsc, sizeof(igtk.pn));
|
|
os_memcpy(igtk.pn, rsc, sizeof(igtk.pn));
|
|
- os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
|
|
|
|
|
|
+ os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], len);
|
|
if (sm->wpa_auth->conf.disable_gtk) {
|
|
if (sm->wpa_auth->conf.disable_gtk) {
|
|
/*
|
|
/*
|
|
* Provide unique random IGTK to each STA to prevent use of
|
|
* Provide unique random IGTK to each STA to prevent use of
|
|
* IGTK in the BSS.
|
|
* IGTK in the BSS.
|
|
*/
|
|
*/
|
|
- if (random_get_bytes(igtk.igtk, WPA_IGTK_LEN) < 0)
|
|
|
|
|
|
+ if (random_get_bytes(igtk.igtk, len) < 0)
|
|
return pos;
|
|
return pos;
|
|
}
|
|
}
|
|
pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
|
|
pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
|
|
- (const u8 *) &igtk, sizeof(igtk), NULL, 0);
|
|
|
|
|
|
+ (const u8 *) &igtk, WPA_IGTK_KDE_PREFIX_LEN + len,
|
|
|
|
+ NULL, 0);
|
|
|
|
|
|
return pos;
|
|
return pos;
|
|
}
|
|
}
|
|
@@ -2457,15 +2461,16 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
|
|
|
|
|
|
#ifdef CONFIG_IEEE80211W
|
|
#ifdef CONFIG_IEEE80211W
|
|
if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
|
if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
|
|
|
+ size_t len;
|
|
|
|
+ len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
|
|
os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
|
|
os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
|
|
inc_byte_array(group->Counter, WPA_NONCE_LEN);
|
|
inc_byte_array(group->Counter, WPA_NONCE_LEN);
|
|
if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
|
|
if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
|
|
wpa_auth->addr, group->GNonce,
|
|
wpa_auth->addr, group->GNonce,
|
|
- group->IGTK[group->GN_igtk - 4],
|
|
|
|
- WPA_IGTK_LEN) < 0)
|
|
|
|
|
|
+ group->IGTK[group->GN_igtk - 4], len) < 0)
|
|
ret = -1;
|
|
ret = -1;
|
|
wpa_hexdump_key(MSG_DEBUG, "IGTK",
|
|
wpa_hexdump_key(MSG_DEBUG, "IGTK",
|
|
- group->IGTK[group->GN_igtk - 4], WPA_IGTK_LEN);
|
|
|
|
|
|
+ group->IGTK[group->GN_igtk - 4], len);
|
|
}
|
|
}
|
|
#endif /* CONFIG_IEEE80211W */
|
|
#endif /* CONFIG_IEEE80211W */
|
|
|
|
|
|
@@ -2582,26 +2587,27 @@ int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos)
|
|
{
|
|
{
|
|
struct wpa_group *gsm = sm->group;
|
|
struct wpa_group *gsm = sm->group;
|
|
u8 *start = pos;
|
|
u8 *start = pos;
|
|
|
|
+ size_t len = wpa_cipher_key_len(sm->wpa_auth->conf.group_mgmt_cipher);
|
|
|
|
|
|
/*
|
|
/*
|
|
* IGTK subelement:
|
|
* IGTK subelement:
|
|
* Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16]
|
|
* Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16]
|
|
*/
|
|
*/
|
|
*pos++ = WNM_SLEEP_SUBELEM_IGTK;
|
|
*pos++ = WNM_SLEEP_SUBELEM_IGTK;
|
|
- *pos++ = 2 + 6 + WPA_IGTK_LEN;
|
|
|
|
|
|
+ *pos++ = 2 + 6 + len;
|
|
WPA_PUT_LE16(pos, gsm->GN_igtk);
|
|
WPA_PUT_LE16(pos, gsm->GN_igtk);
|
|
pos += 2;
|
|
pos += 2;
|
|
if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0)
|
|
if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0)
|
|
return 0;
|
|
return 0;
|
|
pos += 6;
|
|
pos += 6;
|
|
|
|
|
|
- os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
|
|
|
|
- pos += WPA_IGTK_LEN;
|
|
|
|
|
|
+ os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], len);
|
|
|
|
+ pos += len;
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit",
|
|
wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit",
|
|
gsm->GN_igtk);
|
|
gsm->GN_igtk);
|
|
wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit",
|
|
wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit",
|
|
- gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
|
|
|
|
|
|
+ gsm->IGTK[gsm->GN_igtk - 4], len);
|
|
|
|
|
|
return pos - start;
|
|
return pos - start;
|
|
}
|
|
}
|
|
@@ -2656,12 +2662,19 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
|
#ifdef CONFIG_IEEE80211W
|
|
#ifdef CONFIG_IEEE80211W
|
|
- if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION &&
|
|
|
|
- wpa_auth_set_key(wpa_auth, group->vlan_id, WPA_ALG_IGTK,
|
|
|
|
- broadcast_ether_addr, group->GN_igtk,
|
|
|
|
- group->IGTK[group->GN_igtk - 4],
|
|
|
|
- WPA_IGTK_LEN) < 0)
|
|
|
|
- ret = -1;
|
|
|
|
|
|
+ if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
|
|
|
+ enum wpa_alg alg;
|
|
|
|
+ size_t len;
|
|
|
|
+
|
|
|
|
+ alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher);
|
|
|
|
+ len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher);
|
|
|
|
+
|
|
|
|
+ if (ret == 0 &&
|
|
|
|
+ wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
|
|
|
|
+ broadcast_ether_addr, group->GN_igtk,
|
|
|
|
+ group->IGTK[group->GN_igtk - 4], len) < 0)
|
|
|
|
+ ret = -1;
|
|
|
|
+ }
|
|
#endif /* CONFIG_IEEE80211W */
|
|
#endif /* CONFIG_IEEE80211W */
|
|
|
|
|
|
return ret;
|
|
return ret;
|