/**
  * struct cfg80211_gtk_rekey_data - rekey data
- * @kek: key encryption key (NL80211_KEK_LEN bytes)
- * @kck: key confirmation key (NL80211_KCK_LEN bytes)
+ * @kek: key encryption key (@kek_len bytes)
+ * @kck: key confirmation key (@kck_len bytes)
  * @replay_ctr: replay counter (NL80211_REPLAY_CTR_LEN bytes)
+ * @kek_len: length of kek
+ * @kck_len length of kck
+ * @akm: akm (oui, id)
  */
 struct cfg80211_gtk_rekey_data {
        const u8 *kek, *kck, *replay_ctr;
+       u32 akm;
+       u8 kek_len, kck_len;
 };
 
 /**
  *     beaconing mode (AP, IBSS, Mesh, ...).
  * @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation
  *     before connection.
+ * @WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK: The device supports bigger kek and kck keys
  */
 enum wiphy_flags {
-       /* use hole at 0 */
+       WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK         = BIT(0),
        /* use hole at 1 */
        /* use hole at 2 */
        WIPHY_FLAG_NETNS_OK                     = BIT(3),
 
 
 #define NL80211_KCK_LEN                        16
 #define NL80211_KEK_LEN                        16
+#define NL80211_KCK_EXT_LEN            24
+#define NL80211_KEK_EXT_LEN            32
 #define NL80211_REPLAY_CTR_LEN         8
 
 /**
  * @NL80211_REKEY_DATA_KEK: key encryption key (binary)
  * @NL80211_REKEY_DATA_KCK: key confirmation key (binary)
  * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary)
+ * @NL80211_REKEY_DATA_AKM: AKM data (OUI, suite type)
  * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal)
  * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal)
  */
        NL80211_REKEY_DATA_KEK,
        NL80211_REKEY_DATA_KCK,
        NL80211_REKEY_DATA_REPLAY_CTR,
+       NL80211_REKEY_DATA_AKM,
 
        /* keep last */
        NUM_NL80211_REKEY_DATA,
 
 /* policy for GTK rekey offload attributes */
 static const struct nla_policy
 nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
-       [NL80211_REKEY_DATA_KEK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KEK_LEN),
-       [NL80211_REKEY_DATA_KCK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KCK_LEN),
+       [NL80211_REKEY_DATA_KEK] = {
+               .type = NLA_BINARY,
+               .len = NL80211_KEK_EXT_LEN
+       },
+       [NL80211_REKEY_DATA_KCK] = {
+               .type = NLA_BINARY,
+               .len = NL80211_KCK_EXT_LEN
+       },
        [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN_WARN(NL80211_REPLAY_CTR_LEN),
+       [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
 };
 
 static const struct nla_policy
                return -EINVAL;
        if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
                return -ERANGE;
-       if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
+       if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
+           !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
+             nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
                return -ERANGE;
-       if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
+       if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
+           !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
+             nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
                return -ERANGE;
 
        rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
        rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
        rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
+       rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
+       rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
+       if (tb[NL80211_REKEY_DATA_AKM])
+               rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
 
        wdev_lock(wdev);
        if (!wdev->current_bss) {