]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Generate BIGTK and rekey it with IGTK
authorJouni Malinen <jouni@codeaurora.org>
Mon, 17 Feb 2020 21:08:05 +0000 (23:08 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 17 Feb 2020 21:48:24 +0000 (23:48 +0200)
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/wpa_auth.c
src/ap/wpa_auth_i.h

index 0a807a3c65f7d77745d56972ac89df6eddea845e..ee75837db9837bd4881e54c466ebada35e086b92 100644 (file)
@@ -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);
        }
index a993f50089168b4d1a0aa4ab0a7dda059263cb12..c2b22eba13a7e3157d416bfc1decf0e30ddb8bbb 100644 (file)
@@ -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;