.conf.keyidx = key_data->id,
        };
        int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
+       u8 key[WOWLAN_KEY_MAX_SIZE];
 
        BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
        BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
        }
 
        memcpy(conf.conf.key, key_data->key, conf.conf.keylen);
-       key_config = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id);
+
+       memcpy(key, key_data->key, sizeof(key_data->key));
+
+       key_config = ieee80211_gtk_rekey_add(vif, key_data->id, key,
+                                            sizeof(key), link_id);
        if (IS_ERR(key_config))
                return;
 
 
        DEFINE_RAW_FLEX(struct ieee80211_key_conf, conf, key,
                        WOWLAN_KEY_MAX_SIZE);
        int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
+       u8 key_data[WOWLAN_KEY_MAX_SIZE];
 
        conf->cipher = gtk_cipher;
 
                                 conf->cipher, conf->keyidx);
                memcpy(conf->key, status->gtk[i].key,
                       sizeof(status->gtk[i].key));
+               memcpy(key_data, status->gtk[i].key, sizeof(status->gtk[i].key));
 
-               key = ieee80211_gtk_rekey_add(vif, conf, link_id);
+               key = ieee80211_gtk_rekey_add(vif, status->gtk[i].id, key_data,
+                                             sizeof(key_data), link_id);
                if (IS_ERR(key)) {
                        /* FW may send also the old keys */
                        if (PTR_ERR(key) == -EALREADY)
        struct ieee80211_key_conf *key_config;
        struct ieee80211_key_seq seq;
        int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
+       u8 key[WOWLAN_KEY_MAX_SIZE];
        s8 keyidx = key_data->id;
 
        conf->cipher = cipher;
        BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < sizeof(key_data->key));
        memcpy(conf->key, key_data->key, conf->keylen);
 
-       key_config = ieee80211_gtk_rekey_add(vif, conf, link_id);
+       memcpy(key, key_data->key, sizeof(key_data->key));
+
+       key_config = ieee80211_gtk_rekey_add(vif, keyidx, key, sizeof(key),
+                                            link_id);
        if (IS_ERR(key_config)) {
                /* FW may send also the old keys */
                return PTR_ERR(key_config) == -EALREADY;
 
               flex_array_size(rekey_conf, key, cipher_info->len));
 
        if (ieee80211_vif_is_mld(wow_vif))
-               key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id);
+               key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk,
+                                             cipher_info->len,
+                                             rtwvif_link->link_id);
        else
-               key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1);
+               key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk,
+                                             cipher_info->len, -1);
 
        kfree(rekey_conf);
        if (IS_ERR(key)) {
 
 /**
  * ieee80211_gtk_rekey_add - add a GTK key from rekeying during WoWLAN
  * @vif: the virtual interface to add the key on
- * @keyconf: new key data
+ * @idx: the keyidx of the key
+ * @key_data: the key data
+ * @key_len: the key data. Might be bigger than the actual key length,
+ *     but not smaller (for the driver convinence)
  * @link_id: the link id of the key or -1 for non-MLO
  *
  * When GTK rekeying was done while the system was suspended, (a) new
  */
 struct ieee80211_key_conf *
 ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
-                       struct ieee80211_key_conf *keyconf,
+                       u8 idx, u8 *key_data, u8 key_len,
                        int link_id);
 
 /**
 
 
 struct ieee80211_key_conf *
 ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
-                       struct ieee80211_key_conf *keyconf,
+                       u8 idx, u8 *key_data, u8 key_len,
                        int link_id)
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
        struct ieee80211_local *local = sdata->local;
+       struct ieee80211_key *prev_key;
        struct ieee80211_key *key;
        int err;
        struct ieee80211_link_data *link_data =
        if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
                return ERR_PTR(-EINVAL);
 
-       key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx,
-                                 keyconf->keylen, keyconf->key,
+       if (WARN_ON(idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
+                   NUM_DEFAULT_BEACON_KEYS))
+               return ERR_PTR(-EINVAL);
+
+       prev_key = wiphy_dereference(local->hw.wiphy,
+                                    link_data->gtk[idx]);
+       if (!prev_key) {
+               if (idx < NUM_DEFAULT_KEYS) {
+                       for (int i = 0; i < NUM_DEFAULT_KEYS; i++) {
+                               if (i == idx)
+                                       continue;
+                               prev_key = wiphy_dereference(local->hw.wiphy,
+                                                            link_data->gtk[i]);
+                               if (prev_key)
+                                       break;
+                       }
+               } else {
+                       /* For IGTK we have 4 and 5 and for BIGTK - 6 and 7 */
+                       prev_key = wiphy_dereference(local->hw.wiphy,
+                                                    link_data->gtk[idx ^ 1]);
+               }
+       }
+
+       if (WARN_ON(!prev_key))
+               return ERR_PTR(-EINVAL);
+
+       if (WARN_ON(key_len < prev_key->conf.keylen))
+               return ERR_PTR(-EINVAL);
+
+       key = ieee80211_key_alloc(prev_key->conf.cipher, idx,
+                                 prev_key->conf.keylen, key_data,
                                  0, NULL);
        if (IS_ERR(key))
                return ERR_CAST(key);