From: Jouni Malinen Date: Mon, 17 Feb 2020 21:08:05 +0000 (+0200) Subject: Generate BIGTK and rekey it with IGTK X-Git-Tag: hostap_2_10~1791 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=555dcd75ce1ffcb70b55f2f502e951f8cc7bf3fe;p=thirdparty%2Fhostap.git Generate BIGTK and rekey it with IGTK Signed-off-by: Jouni Malinen --- diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 0a807a3c6..ee75837db 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3805,6 +3805,7 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, struct wpa_group *group) { int ret = 0; + size_t len; os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); inc_byte_array(group->Counter, WPA_NONCE_LEN); @@ -3816,7 +3817,6 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, group->GTK[group->GN - 1], group->GTK_len); 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); inc_byte_array(group->Counter, WPA_NONCE_LEN); @@ -3828,6 +3828,19 @@ static int wpa_gtk_update(struct wpa_authenticator *wpa_auth, group->IGTK[group->GN_igtk - 4], len); } + if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION && + wpa_auth->conf.beacon_prot) { + len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); + os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN); + inc_byte_array(group->Counter, WPA_NONCE_LEN); + if (wpa_gmk_to_gtk(group->GMK, "BIGTK key expansion", + wpa_auth->addr, group->GNonce, + group->BIGTK[group->GN_bigtk - 6], len) < 0) + ret = -1; + wpa_hexdump_key(MSG_DEBUG, "BIGTK", + group->BIGTK[group->GN_bigtk - 6], len); + } + return ret; } @@ -3846,6 +3859,8 @@ static void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth, group->GM = 2; group->GN_igtk = 4; group->GM_igtk = 5; + group->GN_bigtk = 6; + group->GM_bigtk = 7; /* GTK[GN] = CalcGTK() */ wpa_gtk_update(wpa_auth, group); } @@ -3982,6 +3997,9 @@ static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, tmp = group->GM_igtk; group->GM_igtk = group->GN_igtk; group->GN_igtk = tmp; + tmp = group->GM_bigtk; + group->GM_bigtk = group->GN_bigtk; + group->GN_bigtk = tmp; /* "GKeyDoneStations = GNoStations" is done in more robust way by * counting the STAs that are marked with GUpdateStationKeys instead of * including all STAs that could be in not-yet-completed state. */ @@ -4024,6 +4042,13 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, group->IGTK[group->GN_igtk - 4], len, KEY_FLAG_GROUP_TX_DEFAULT) < 0) ret = -1; + + if (ret == 0 && wpa_auth->conf.beacon_prot && + wpa_auth_set_key(wpa_auth, group->vlan_id, alg, + broadcast_ether_addr, group->GN_bigtk, + group->BIGTK[group->GN_bigtk - 6], len, + KEY_FLAG_GROUP_TX_DEFAULT) < 0) + ret = -1; } return ret; @@ -4165,6 +4190,9 @@ void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth) tmp = group->GM_igtk; group->GM_igtk = group->GN_igtk; group->GN_igtk = tmp; + tmp = group->GM_bigtk; + group->GM_bigtk = group->GN_bigtk; + group->GN_bigtk = tmp; wpa_gtk_update(wpa_auth, group); wpa_group_config_group_keys(wpa_auth, group); } diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index a993f5008..c2b22eba1 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -193,7 +193,9 @@ struct wpa_group { Boolean first_sta_seen; Boolean reject_4way_hs_for_entropy; u8 IGTK[2][WPA_IGTK_MAX_LEN]; + u8 BIGTK[2][WPA_IGTK_MAX_LEN]; int GN_igtk, GM_igtk; + int GN_bigtk, GM_bigtk; /* Number of references except those in struct wpa_group->next */ unsigned int references; unsigned int num_setup_iface;