]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Introduce and add key_flag
authorAlexander Wetzel <alexander@wetzel-home.de>
Sat, 4 Jan 2020 22:10:04 +0000 (23:10 +0100)
committerJouni Malinen <j@w1.fi>
Thu, 9 Jan 2020 10:38:36 +0000 (12:38 +0200)
Add the new set_key() parameter "key_flag" to provide more specific
description of what type of a key is being configured. This is needed to
be able to add support for "Extended Key ID for Individually Addressed
Frames" from IEEE Std 802.11-2016. In addition, this may be used to
replace the set_tx boolean eventually once all the driver wrappers have
moved to using the new key_flag.

The following flag are defined:

  KEY_FLAG_MODIFY
    Set when an already installed key must be updated.
    So far the only use-case is changing RX/TX status of installed
    keys. Must not be set when deleting a key.

  KEY_FLAG_DEFAULT
    Set when the key is also a default key. Must not be set when
    deleting a key. (This is the replacement for set_tx.)

  KEY_FLAG_RX
    The key is valid for RX. Must not be set when deleting a key.

  KEY_FLAG_TX
    The key is valid for TX. Must not be set when deleting a key.

  KEY_FLAG_GROUP
    The key is a broadcast or group key.

  KEY_FLAG_PAIRWISE
    The key is a pairwise key.

  KEY_FLAG_PMK
    The key is a Pairwise Master Key (PMK).

Predefined and needed flag combinations so far are:

  KEY_FLAG_GROUP_RX_TX
    WEP key not used as default key (yet).

  KEY_FLAG_GROUP_RX_TX_DEFAULT
    Default WEP or WPA-NONE key.

  KEY_FLAG_GROUP_RX
    GTK key valid for RX only.

  KEY_FLAG_GROUP_TX_DEFAULT
    GTK key valid for TX only, immediately taking over TX.

  KEY_FLAG_PAIRWISE_RX_TX
    Pairwise key immediately becoming the active pairwise key.

  KEY_FLAG_PAIRWISE_RX
    Pairwise key not yet valid for TX. (Only usable with Extended Key ID
    support.)

  KEY_FLAG_PAIRWISE_RX_TX_MODIFY
    Enable TX for a pairwise key installed with KEY_FLAG_PAIRWISE_RX.

  KEY_FLAG_RX_TX
    Not a valid standalone key type and can only used in combination
    with other flags to mark a key for RX/TX.

This commit is not changing any functionality. It just adds the new
key_flag to all hostapd/wpa_supplicant set_key() functions without using
it, yet.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
25 files changed:
hostapd/ctrl_iface.c
src/ap/ap_drv_ops.c
src/ap/ap_drv_ops.h
src/ap/hostapd.c
src/ap/ieee802_11.c
src/ap/ieee802_1x.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_glue.c
src/common/defs.h
src/drivers/driver.h
src/rsn_supp/tdls.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_ft.c
src/rsn_supp/wpa_i.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/driver_i.h
wpa_supplicant/ibss_rsn.c
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_rsn.c
wpa_supplicant/preauth_test.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpas_glue.c

index af49551848aba4cfe24677c9f9928f2dd4a4765e..8ef57e5aa295c6307c15a3d6e404f92543dad7d9 100644 (file)
@@ -2155,7 +2155,8 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
                                        hapd->last_igtk_alg,
                                        broadcast_ether_addr,
                                        hapd->last_igtk_key_idx, 0, 1, NULL, 0,
-                                       zero, hapd->last_igtk_len) < 0)
+                                       zero, hapd->last_igtk_len,
+                                       KEY_FLAG_GROUP_TX_DEFAULT) < 0)
                        return -1;
 
                /* Set the previously configured key to reset its TSC */
@@ -2164,7 +2165,8 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
                                           broadcast_ether_addr,
                                           hapd->last_igtk_key_idx, 0, 1, NULL,
                                           0, hapd->last_igtk,
-                                          hapd->last_igtk_len);
+                                          hapd->last_igtk_len,
+                                          KEY_FLAG_GROUP_TX_DEFAULT);
        }
 
        if (is_broadcast_ether_addr(addr)) {
@@ -2179,7 +2181,8 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
                                        hapd->last_gtk_alg,
                                        broadcast_ether_addr,
                                        hapd->last_gtk_key_idx, 0, 1, NULL, 0,
-                                       zero, hapd->last_gtk_len) < 0)
+                                       zero, hapd->last_gtk_len,
+                                       KEY_FLAG_GROUP_TX_DEFAULT) < 0)
                        return -1;
 
                /* Set the previously configured key to reset its TSC */
@@ -2188,7 +2191,8 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
                                           broadcast_ether_addr,
                                           hapd->last_gtk_key_idx, 0, 1, NULL,
                                           0, hapd->last_gtk,
-                                          hapd->last_gtk_len);
+                                          hapd->last_gtk_len,
+                                          KEY_FLAG_GROUP_TX_DEFAULT);
        }
 
        sta = ap_get_sta(hapd, addr);
@@ -2205,13 +2209,15 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
         * in the driver. */
        if (hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
                                sta->addr, sta->last_tk_key_idx, 0, 1, NULL, 0,
-                               zero, sta->last_tk_len) < 0)
+                               zero, sta->last_tk_len,
+                               KEY_FLAG_PAIRWISE_RX_TX) < 0)
                return -1;
 
        /* Set the previously configured key to reset its TSC/RSC */
        return hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
                                   sta->addr, sta->last_tk_key_idx, 0, 1, NULL,
-                                  0, sta->last_tk, sta->last_tk_len);
+                                  0, sta->last_tk, sta->last_tk_len,
+                                  KEY_FLAG_PAIRWISE_RX_TX);
 }
 
 
@@ -2259,7 +2265,7 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd)
 
        wpa_printf(MSG_INFO, "TESTING: Set key");
        return hostapd_drv_set_key(hapd->conf->iface, hapd, alg, addr, idx, 0,
-                                  set_tx, seq, 6, key, key_len);
+                                  set_tx, seq, 6, key, key_len, 0);
 }
 
 
@@ -2275,7 +2281,8 @@ static void restore_tk(void *ctx1, void *ctx2)
         * preventing encryption of a single EAPOL frame. */
        hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
                            sta->addr, sta->last_tk_key_idx, 0, 1, NULL, 0,
-                           sta->last_tk, sta->last_tk_len);
+                           sta->last_tk, sta->last_tk_len,
+                           KEY_FLAG_PAIRWISE_RX_TX);
 }
 
 
@@ -2299,7 +2306,7 @@ static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd)
                           MAC2STR(sta->addr));
                hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
                                    sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
-                                   0, NULL, 0);
+                                   0, NULL, 0, KEY_FLAG_PAIRWISE);
        }
 
        wpa_printf(MSG_INFO, "TESTING: Send M1 to " MACSTR, MAC2STR(sta->addr));
@@ -2329,7 +2336,7 @@ static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd)
                           MAC2STR(sta->addr));
                hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
                                    sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
-                                   0, NULL, 0);
+                                   0, NULL, 0, KEY_FLAG_PAIRWISE);
        }
 
        wpa_printf(MSG_INFO, "TESTING: Send M3 to " MACSTR, MAC2STR(sta->addr));
@@ -2359,7 +2366,7 @@ static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd,
                           MAC2STR(sta->addr));
                hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
                                    sta->addr, sta->last_tk_key_idx, 0, 0, NULL,
-                                   0, NULL, 0);
+                                   0, NULL, 0, KEY_FLAG_PAIRWISE);
        }
 
        wpa_printf(MSG_INFO,
index 74f011806341c6b0a5da3ef6ebb55ed8779dd46e..c217d9b245e746ae51964dc92c866a0c3b748e53 100644 (file)
@@ -682,7 +682,7 @@ int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
                        enum wpa_alg alg, const u8 *addr,
                        int key_idx, int vlan_id, int set_tx,
                        const u8 *seq, size_t seq_len,
-                       const u8 *key, size_t key_len)
+                       const u8 *key, size_t key_len, enum key_flag key_flag)
 {
        struct wpa_driver_set_key_params params;
 
@@ -700,6 +700,7 @@ int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
        params.key = key;
        params.key_len = key_len;
        params.vlan_id = vlan_id;
+       params.key_flag = key_flag;
 
        return hapd->driver->set_key(hapd->drv_priv, &params);
 }
index 30547b713cf9c420bd925f5967f43753dd566b75..56d1ad86266b6cb7b9cb5dde5a350d0dfbf4e999 100644 (file)
@@ -91,7 +91,7 @@ int hostapd_drv_set_key(const char *ifname,
                        enum wpa_alg alg, const u8 *addr,
                        int key_idx, int vlan_id, int set_tx,
                        const u8 *seq, size_t seq_len,
-                       const u8 *key, size_t key_len);
+                       const u8 *key, size_t key_len, enum key_flag key_flag);
 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
                          const void *msg, size_t len, int noack,
                          const u16 *csa_offs, size_t csa_offs_len,
index 3fb493ae540a2b3acb1d02f108a1da87d8863ab2..b87663fe9329b7774ba528f72f9e0b02af23ca63 100644 (file)
@@ -293,7 +293,7 @@ static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
                return;
        for (i = 0; i < NUM_WEP_KEYS; i++) {
                if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
-                                       0, NULL, 0, NULL, 0)) {
+                                       0, NULL, 0, NULL, 0, KEY_FLAG_GROUP)) {
                        wpa_printf(MSG_DEBUG, "Failed to clear default "
                                   "encryption keys (ifname=%s keyidx=%d)",
                                   ifname, i);
@@ -303,7 +303,7 @@ static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
                for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
                        if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
                                                NULL, i, 0, 0, NULL,
-                                               0, NULL, 0)) {
+                                               0, NULL, 0, KEY_FLAG_GROUP)) {
                                wpa_printf(MSG_DEBUG, "Failed to clear "
                                           "default mgmt encryption keys "
                                           "(ifname=%s keyidx=%d)", ifname, i);
@@ -330,7 +330,8 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
            hostapd_drv_set_key(hapd->conf->iface,
                                hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
                                1, NULL, 0, ssid->wep.key[idx],
-                               ssid->wep.len[idx])) {
+                               ssid->wep.len[idx],
+                               KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
                wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
                errors++;
        }
@@ -556,7 +557,10 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
                    hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 0,
                                        i == hapd->conf->ssid.wep.idx, NULL, 0,
                                        hapd->conf->ssid.wep.key[i],
-                                       hapd->conf->ssid.wep.len[i])) {
+                                       hapd->conf->ssid.wep.len[i],
+                                       i == hapd->conf->ssid.wep.idx ?
+                                       KEY_FLAG_GROUP_RX_TX_DEFAULT :
+                                       KEY_FLAG_GROUP_RX_TX)) {
                        wpa_printf(MSG_WARNING, "Could not set WEP "
                                   "encryption.");
                        return -1;
index aa8b828bec75e7940be455c61887bcbf5e3ecd93..cd61077944a9624c5a59c82ca53dad5e3d5b6353 100644 (file)
@@ -4912,7 +4912,10 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
                if (ssid->wep.key[i] &&
                    hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
                                        0, i == ssid->wep.idx, NULL, 0,
-                                       ssid->wep.key[i], ssid->wep.len[i])) {
+                                       ssid->wep.key[i], ssid->wep.len[i],
+                                       i == ssid->wep.idx ?
+                                       KEY_FLAG_GROUP_RX_TX_DEFAULT :
+                                       KEY_FLAG_GROUP_RX_TX)) {
                        wpa_printf(MSG_WARNING,
                                   "Could not set WEP keys for WDS interface; %s",
                                   ifname_wds);
index 4bcaec9dab7d6615a40333d70198b35698e9415e..001b26109147311143488f44fb2fd5e76f3cc1bb 100644 (file)
@@ -285,7 +285,8 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
                 * has ACKed EAPOL-Key frame */
                if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
                                        sta->addr, 0, 0, 1, NULL, 0, ikey,
-                                       hapd->conf->individual_wep_key_len)) {
+                                       hapd->conf->individual_wep_key_len,
+                                       KEY_FLAG_PAIRWISE_RX_TX)) {
                        wpa_printf(MSG_ERROR,
                                   "Could not set individual WEP encryption");
                }
@@ -2179,7 +2180,8 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
                                broadcast_ether_addr,
                                eapol->default_wep_key_idx, 0, 1, NULL, 0,
                                eapol->default_wep_key,
-                               hapd->conf->default_wep_key_len)) {
+                               hapd->conf->default_wep_key_len,
+                               KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
                hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
                               HOSTAPD_LEVEL_WARNING,
                               "failed to configure a new broadcast key");
@@ -2471,7 +2473,7 @@ int ieee802_1x_init(struct hostapd_data *hapd)
                for (i = 0; i < 4; i++)
                        hostapd_drv_set_key(hapd->conf->iface, hapd,
                                            WPA_ALG_NONE, NULL, i, 0, 0, NULL,
-                                           0, NULL, 0);
+                                           0, NULL, 0, KEY_FLAG_GROUP_RX_TX);
 
                ieee802_1x_rekey(hapd, NULL);
 
index 8103ef8a30334fc65e315adaf165631f1ba9671f..423528d128e338e511a3b0a7917a4336e409f02e 100644 (file)
@@ -136,12 +136,13 @@ static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
 static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
                                   int vlan_id,
                                   enum wpa_alg alg, const u8 *addr, int idx,
-                                  u8 *key, size_t key_len)
+                                  u8 *key, size_t key_len,
+                                  enum key_flag key_flag)
 {
        if (wpa_auth->cb->set_key == NULL)
                return -1;
        return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
-                                    key, key_len);
+                                    key, key_len, key_flag);
 }
 
 
@@ -1738,7 +1739,7 @@ void wpa_remove_ptk(struct wpa_state_machine *sm)
        sm->PTK_valid = FALSE;
        os_memset(&sm->PTK, 0, sizeof(sm->PTK));
        if (wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL,
-                            0))
+                            0, KEY_FLAG_PAIRWISE))
                wpa_printf(MSG_DEBUG,
                           "RSN: PTK removal from the driver failed");
        sm->pairwise_set = FALSE;
@@ -2771,7 +2772,7 @@ int fils_set_tk(struct wpa_state_machine *sm)
 
        wpa_printf(MSG_DEBUG, "FILS: Configure TK to the driver");
        if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-                            sm->PTK.tk, klen)) {
+                            sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX)) {
                wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
                return -1;
        }
@@ -3396,7 +3397,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
                enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
                int klen = wpa_cipher_key_len(sm->pairwise);
                if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-                                    sm->PTK.tk, klen)) {
+                                    sm->PTK.tk, klen,
+                                    KEY_FLAG_PAIRWISE_RX_TX)) {
                        wpa_sta_disconnect(sm->wpa_auth, sm->addr,
                                           WLAN_REASON_PREV_AUTH_NOT_VALID);
                        return;
@@ -3988,7 +3990,8 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
        if (wpa_auth_set_key(wpa_auth, group->vlan_id,
                             wpa_cipher_to_alg(wpa_auth->conf.wpa_group),
                             broadcast_ether_addr, group->GN,
-                            group->GTK[group->GN - 1], group->GTK_len) < 0)
+                            group->GTK[group->GN - 1], group->GTK_len,
+                            KEY_FLAG_GROUP_TX_DEFAULT) < 0)
                ret = -1;
 
        if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
@@ -4001,7 +4004,8 @@ static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
                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)
+                                    group->IGTK[group->GN_igtk - 4], len,
+                                    KEY_FLAG_GROUP_TX_DEFAULT) < 0)
                        ret = -1;
        }
 
index 3b4fd74e2f8fd8457a5e0de10a5ed486787bc421..0b4b7297c18ee301cb147d67a9e8df4e7788883a 100644 (file)
@@ -263,7 +263,8 @@ struct wpa_auth_callbacks {
                              int *vlan_id);
        int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len);
        int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg,
-                      const u8 *addr, int idx, u8 *key, size_t key_len);
+                      const u8 *addr, int idx, u8 *key, size_t key_len,
+                      enum key_flag key_flag);
        int (*get_seqnum)(void *ctx, const u8 *addr, int idx, u8 *seq);
        int (*send_eapol)(void *ctx, const u8 *addr, const u8 *data,
                          size_t data_len, int encrypt);
index d24feb560d9cf6435ea3b9fb5da3eca9144a2bc4..462876195a0879a5ad93c0a67df546b300fde7dc 100644 (file)
@@ -2622,12 +2622,13 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
 static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
                                   int vlan_id,
                                   enum wpa_alg alg, const u8 *addr, int idx,
-                                  u8 *key, size_t key_len)
+                                  u8 *key, size_t key_len,
+                                  enum key_flag key_flag)
 {
        if (wpa_auth->cb->set_key == NULL)
                return -1;
        return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
-                                    key, key_len);
+                                    key, key_len, key_flag);
 }
 
 
@@ -2660,7 +2661,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
         * optimized by adding the STA entry earlier.
         */
        if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-                            sm->PTK.tk, klen))
+                            sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX))
                return;
 
        /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
index e871cc900a5181e58ab183e8aaf5eec41288218a..e643046368a38346114e04f035dcefa054d9bfa9 100644 (file)
@@ -378,7 +378,7 @@ static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk,
 
 static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
                                    const u8 *addr, int idx, u8 *key,
-                                   size_t key_len)
+                                   size_t key_len, enum key_flag key_flag)
 {
        struct hostapd_data *hapd = ctx;
        const char *ifname = hapd->conf->iface;
@@ -423,7 +423,7 @@ static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
        }
 #endif /* CONFIG_TESTING_OPTIONS */
        return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, vlan_id, 1,
-                                  NULL, 0, key, key_len);
+                                  NULL, 0, key, key_len, key_flag);
 }
 
 
index e2fa4b291e0022619f947f401f70ab8348658760..5e22278e6bc0ddda39ed0fcefc88cff9ac68d2c0 100644 (file)
@@ -423,4 +423,26 @@ enum chan_width {
        CHAN_WIDTH_UNKNOWN
 };
 
+enum key_flag {
+       KEY_FLAG_MODIFY                 = BIT(0),
+       KEY_FLAG_DEFAULT                = BIT(1),
+       KEY_FLAG_RX                     = BIT(2),
+       KEY_FLAG_TX                     = BIT(3),
+       KEY_FLAG_GROUP                  = BIT(4),
+       KEY_FLAG_PAIRWISE               = BIT(5),
+       KEY_FLAG_PMK                    = BIT(6),
+       /* Used flag combinations */
+       KEY_FLAG_RX_TX                  = KEY_FLAG_RX | KEY_FLAG_TX,
+       KEY_FLAG_GROUP_RX_TX            = KEY_FLAG_GROUP | KEY_FLAG_RX_TX,
+       KEY_FLAG_GROUP_RX_TX_DEFAULT    = KEY_FLAG_GROUP_RX_TX |
+                                         KEY_FLAG_DEFAULT,
+       KEY_FLAG_GROUP_RX               = KEY_FLAG_GROUP | KEY_FLAG_RX,
+       KEY_FLAG_GROUP_TX_DEFAULT       = KEY_FLAG_GROUP | KEY_FLAG_TX |
+                                         KEY_FLAG_DEFAULT,
+       KEY_FLAG_PAIRWISE_RX_TX         = KEY_FLAG_PAIRWISE | KEY_FLAG_RX_TX,
+       KEY_FLAG_PAIRWISE_RX            = KEY_FLAG_PAIRWISE | KEY_FLAG_RX,
+       KEY_FLAG_PAIRWISE_RX_TX_MODIFY  = KEY_FLAG_PAIRWISE_RX_TX |
+                                         KEY_FLAG_MODIFY,
+};
+
 #endif /* DEFS_H */
index 1301babd5224cb9f97ad8c2fe51e841a06773da1..c37dd2fc99e7399517208c42c262cb989a0267e5 100644 (file)
@@ -1592,6 +1592,51 @@ struct wpa_driver_set_key_params {
        /**
         * vlan_id - VLAN index (0..4095) for VLAN offload cases */
        int vlan_id;
+
+       /**
+        * key_flag - Additional key flags
+        *
+        * %KEY_FLAG_MODIFY
+        *  Set when an already installed key must be updated.
+        *  So far the only use-case is changing RX/TX status of
+        *  installed keys. Must not be set when deleting a key.
+        * %KEY_FLAG_DEFAULT
+        *  Set when the key is also a default key. Must not be set when
+        *  deleting a key.
+        * %KEY_FLAG_RX
+        *  The key is valid for RX. Must not be set when deleting a key.
+        * %KEY_FLAG_TX
+        *  The key is valid for TX. Must not be set when deleting a key.
+        * %KEY_FLAG_GROUP
+        *  The key is a broadcast or group key.
+        * %KEY_FLAG_PAIRWISE
+        *  The key is a pairwise key.
+        * %KEY_FLAG_PMK
+        *  The key is a Pairwise Master Key (PMK).
+        *
+        * Valid and pre-defined combinations are:
+        * %KEY_FLAG_GROUP_RX_TX
+        *  WEP key not to be installed as default key.
+        * %KEY_FLAG_GROUP_RX_TX_DEFAULT
+        *  Default WEP or WPA-NONE key.
+        * %KEY_FLAG_GROUP_RX
+        *  GTK key valid for RX only.
+        * %KEY_FLAG_GROUP_TX_DEFAULT
+        *  GTK key valid for TX only, immediately taking over TX.
+        * %KEY_FLAG_PAIRWISE_RX_TX
+        *  Pairwise key immediately becoming the active pairwise key.
+        * %KEY_FLAG_PAIRWISE_RX
+        *  Pairwise key not yet valid for TX. (Only usable when Extended
+        *  Key ID is supported by the driver.)
+        * %KEY_FLAG_PAIRWISE_RX_TX_MODIFY
+        *  Enable TX for a pairwise key installed with
+        *  KEY_FLAG_PAIRWISE_RX.
+        *
+        * Not a valid standalone key type but pre-defined to be combined
+        * with other key_flags:
+        * %KEY_FLAG_RX_TX
+        *  RX/TX key. */
+       enum key_flag key_flag;
 };
 
 /**
index 704c95e68616971f96e5f17bb10d0fc23df2e91b..bb8973942eb96bf132929196fe69f592d18aca42 100644 (file)
@@ -178,7 +178,7 @@ static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
 static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
 {
        if (wpa_sm_set_key(sm, WPA_ALG_NONE, peer->addr,
-                          0, 0, NULL, 0, NULL, 0) < 0) {
+                          0, 0, NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE) < 0) {
                wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from "
                           "the driver");
                return -1;
@@ -227,8 +227,9 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
 
        wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
                   MAC2STR(peer->addr));
-       if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
-                          rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
+       if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, rsc, sizeof(rsc),
+                          peer->tpk.tk, key_len,
+                          KEY_FLAG_PAIRWISE_RX_TX) < 0) {
                wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
                           "driver");
                return -1;
index 85c28401b48f75b102a0c5805fef2c9a27ae5ccf..5f08d0e78e67cbc0d5de2d688c7d872d7c1f2675 100644 (file)
@@ -789,7 +789,8 @@ static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
 
 
 static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
-                                     const struct wpa_eapol_key *key)
+                                     const struct wpa_eapol_key *key,
+                                     enum key_flag key_flag)
 {
        int keylen, rsclen;
        enum wpa_alg alg;
@@ -834,7 +835,8 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
        }
 
        if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
-                          sm->ptk.tk, keylen) < 0) {
+                          sm->ptk.tk, keylen,
+                          KEY_FLAG_PAIRWISE | key_flag) < 0) {
                wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
                        "WPA: Failed to set PTK to the "
                        "driver (alg=%d keylen=%d bssid=" MACSTR ")",
@@ -927,7 +929,8 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
        if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
                if (wpa_sm_set_key(sm, gd->alg, NULL,
                                   gd->keyidx, 1, key_rsc, gd->key_rsc_len,
-                                  _gtk, gd->gtk_len) < 0) {
+                                  _gtk, gd->gtk_len,
+                                  KEY_FLAG_GROUP_RX_TX_DEFAULT) < 0) {
                        wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
                                "WPA: Failed to set GTK to the driver "
                                "(Group only)");
@@ -936,7 +939,7 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
                }
        } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
                                  gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
-                                 _gtk, gd->gtk_len) < 0) {
+                                 _gtk, gd->gtk_len, KEY_FLAG_GROUP_RX) < 0) {
                wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
                        "WPA: Failed to set GTK to "
                        "the driver (alg=%d keylen=%d keyidx=%d)",
@@ -1090,7 +1093,7 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
        if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
                           broadcast_ether_addr,
                           keyidx, 0, igtk->pn, sizeof(igtk->pn),
-                          igtk->igtk, len) < 0) {
+                          igtk->igtk, len, KEY_FLAG_GROUP_RX) < 0) {
                if (keyidx == 0x0400 || keyidx == 0x0500) {
                        /* Assume the AP has broken PMF implementation since it
                         * seems to have swapped the KeyID bytes. The AP cannot
@@ -1542,7 +1545,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
        sm->renew_snonce = 1;
 
        if (key_info & WPA_KEY_INFO_INSTALL) {
-               if (wpa_supplicant_install_ptk(sm, key))
+               if (wpa_supplicant_install_ptk(sm, key, KEY_FLAG_RX_TX))
                        goto failed;
        }
 
@@ -4574,7 +4577,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
        wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
                        sm->ptk.tk, keylen);
        if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, null_rsc, rsclen,
-                          sm->ptk.tk, keylen) < 0) {
+                          sm->ptk.tk, keylen, KEY_FLAG_PAIRWISE_RX_TX) < 0) {
                wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
                        "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
                        MACSTR ")",
index 31a8bd0c6e9aa9b6f7d829d08a6a062e7d6e8188..85fedeeae0d193daa17e625e7b439a265fdf6b89 100644 (file)
@@ -30,7 +30,7 @@ struct wpa_sm_ctx {
        int (*set_key)(void *ctx, enum wpa_alg alg,
                       const u8 *addr, int key_idx, int set_tx,
                       const u8 *seq, size_t seq_len,
-                      const u8 *key, size_t key_len);
+                      const u8 *key, size_t key_len, enum key_flag key_flag);
        void * (*get_network_ctx)(void *ctx);
        int (*get_bssid)(void *ctx, u8 *bssid);
        int (*ether_send)(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
index 2b8b41fa5852ed008069b9e1207e43f67589f234..8a8c545d38fa99ad9a1f39d8add80f445ba4179c 100644 (file)
@@ -422,8 +422,9 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
        alg = wpa_cipher_to_alg(sm->pairwise_cipher);
        keylen = wpa_cipher_key_len(sm->pairwise_cipher);
 
-       if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc,
-                          sizeof(null_rsc), (u8 *) sm->ptk.tk, keylen) < 0) {
+       if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc, sizeof(null_rsc),
+                          (u8 *) sm->ptk.tk, keylen,
+                          KEY_FLAG_PAIRWISE_RX_TX) < 0) {
                wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver");
                return -1;
        }
@@ -773,7 +774,8 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
                os_memcpy(gtk + 24, tmp, 8);
        }
        if (wpa_sm_set_key(sm, alg, broadcast_ether_addr, keyidx, 0,
-                          gtk_elem + 3, rsc_len, gtk, keylen) < 0) {
+                          gtk_elem + 3, rsc_len, gtk, keylen,
+                          KEY_FLAG_GROUP_RX) < 0) {
                wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
                           "driver.");
                return -1;
@@ -840,7 +842,8 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
                        igtk_len);
        if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
                           broadcast_ether_addr, keyidx, 0,
-                          igtk_elem + 2, 6, igtk, igtk_len) < 0) {
+                          igtk_elem + 2, 6, igtk, igtk_len,
+                          KEY_FLAG_GROUP_RX) < 0) {
                wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the "
                           "driver.");
                forced_memzero(igtk, sizeof(igtk));
index 2a433425c75ff0885d095ee574c34c2d95c3620a..7d7c06ef2b0b25684020449aed097675835e3bda 100644 (file)
@@ -198,11 +198,12 @@ static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code)
 static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg,
                                 const u8 *addr, int key_idx, int set_tx,
                                 const u8 *seq, size_t seq_len,
-                                const u8 *key, size_t key_len)
+                                const u8 *key, size_t key_len,
+                                enum key_flag key_flag)
 {
        WPA_ASSERT(sm->ctx->set_key);
        return sm->ctx->set_key(sm->ctx->ctx, alg, addr, key_idx, set_tx,
-                               seq, seq_len, key, key_len);
+                               seq, seq_len, key, key_len, key_flag);
 }
 
 static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm)
index 339d8198c49cf10d60f16f402a6e2681982876c8..65dcb90f1647679c1024eb43d7d5a390b3b46dd1 100644 (file)
@@ -5345,15 +5345,21 @@ static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
 {
        wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
        /* MLME-DELETEKEYS.request */
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
-       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
+       wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL,
+                       0, KEY_FLAG_GROUP);
 
        wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
-                       0);
+                       0, KEY_FLAG_PAIRWISE);
        /* MLME-SETPROTECTION.request(None) */
        wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
                                   MLME_SETPROTECTION_PROTECT_TYPE_NONE,
@@ -9351,13 +9357,15 @@ static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s)
         * in the driver. */
        if (wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
                            wpa_s->last_tk_key_idx, 1, zero, 6,
-                           zero, wpa_s->last_tk_len) < 0)
+                           zero, wpa_s->last_tk_len,
+                           KEY_FLAG_PAIRWISE_RX_TX) < 0)
                return -1;
 
        /* Set the previously configured key to reset its TSC/RSC */
        return wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
                               wpa_s->last_tk_key_idx, 1, zero, 6,
-                              wpa_s->last_tk, wpa_s->last_tk_len);
+                              wpa_s->last_tk, wpa_s->last_tk_len,
+                              KEY_FLAG_PAIRWISE_RX_TX);
 }
 
 
index e425ea145ae6a04637102f8d51409a66c6cf1542..45b62bdea28589e2dc4518ce3a1c0b5a2a4bb719 100644 (file)
@@ -147,7 +147,8 @@ static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
                                  enum wpa_alg alg, const u8 *addr,
                                  int key_idx, int set_tx,
                                  const u8 *seq, size_t seq_len,
-                                 const u8 *key, size_t key_len)
+                                 const u8 *key, size_t key_len,
+                                 enum key_flag key_flag)
 {
        struct wpa_driver_set_key_params params;
 
@@ -161,6 +162,7 @@ static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
        params.seq_len = seq_len;
        params.key = key;
        params.key_len = key_len;
+       params.key_flag = key_flag;
 
        if (alg != WPA_ALG_NONE) {
                if (key_idx >= 0 && key_idx <= 6)
index a3b5164c005bceccf7c3002090040bffd4b6c68e..37368c4cb388146802ddd33dc9ddc393d3b2b0ff 100644 (file)
@@ -146,7 +146,7 @@ static void ibss_check_rsn_completed(struct ibss_rsn_peer *peer)
 static int supp_set_key(void *ctx, enum wpa_alg alg,
                        const u8 *addr, int key_idx, int set_tx,
                        const u8 *seq, size_t seq_len,
-                       const u8 *key, size_t key_len)
+                       const u8 *key, size_t key_len, enum key_flag key_flag)
 {
        struct ibss_rsn_peer *peer = ctx;
 
@@ -173,7 +173,7 @@ static int supp_set_key(void *ctx, enum wpa_alg alg,
        if (is_broadcast_ether_addr(addr))
                addr = peer->addr;
        return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx,
-                              set_tx, seq, seq_len, key, key_len);
+                              set_tx, seq, seq_len, key, key_len, key_flag);
 }
 
 
@@ -306,7 +306,8 @@ static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
 
 
 static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
-                       const u8 *addr, int idx, u8 *key, size_t key_len)
+                       const u8 *addr, int idx, u8 *key, size_t key_len,
+                       enum key_flag key_flag)
 {
        struct ibss_rsn *ibss_rsn = ctx;
        u8 seq[6];
@@ -345,7 +346,7 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
        }
 
        return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
-                              1, seq, 6, key, key_len);
+                              1, seq, 6, key, key_len, key_flag);
 }
 
 
@@ -858,7 +859,7 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn,
                wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer "
                           MACSTR, MAC2STR(addr));
                wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0,
-                               NULL, 0, NULL, 0);
+                               NULL, 0, NULL, 0, KEY_FLAG_PAIRWISE);
        }
 
        if (peer &&
index c7c85929f561d989a26c168cb4a6ed3ddb847772..31dd1d3c6ca5939f90c18c8ece3bfa295f26247a 100644 (file)
@@ -877,7 +877,8 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
                wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
                wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
                                sta->addr, 0, 0, seq, sizeof(seq),
-                               sta->mtk, sta->mtk_len);
+                               sta->mtk, sta->mtk_len,
+                               KEY_FLAG_PAIRWISE_RX_TX);
 
                wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
                                sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
@@ -886,7 +887,8 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
                wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
                                sta->addr, sta->mgtk_key_id, 0,
                                sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
-                               sta->mgtk, sta->mgtk_len);
+                               sta->mgtk, sta->mgtk_len,
+                               KEY_FLAG_GROUP_RX);
 
                if (sta->igtk_len) {
                        wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
@@ -898,7 +900,8 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
                                wpa_cipher_to_alg(conf->mgmt_group_cipher),
                                sta->addr, sta->igtk_key_id, 0,
                                sta->igtk_rsc, sizeof(sta->igtk_rsc),
-                               sta->igtk, sta->igtk_len);
+                               sta->igtk, sta->igtk_len,
+                               KEY_FLAG_GROUP_RX);
                }
        }
 
index e730b6336c7d454e06bfc284c4836858bed3d3c6..f19bfbfc679fa46add4e9af48be2aa8a241014d9 100644 (file)
@@ -100,7 +100,8 @@ static const u8 *auth_get_psk(void *ctx, const u8 *addr,
 
 
 static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
-                       const u8 *addr, int idx, u8 *key, size_t key_len)
+                       const u8 *addr, int idx, u8 *key, size_t key_len,
+                       enum key_flag key_flag)
 {
        struct mesh_rsn *mesh_rsn = ctx;
        u8 seq[6];
@@ -118,7 +119,7 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
        wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);
 
        return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx,
-                              1, seq, 6, key, key_len);
+                              1, seq, 6, key, key_len, key_flag);
 }
 
 
@@ -196,7 +197,8 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
                wpa_drv_set_key(rsn->wpa_s,
                                wpa_cipher_to_alg(rsn->mgmt_group_cipher), NULL,
                                rsn->igtk_key_id, 1,
-                               seq, sizeof(seq), rsn->igtk, rsn->igtk_len);
+                               seq, sizeof(seq), rsn->igtk, rsn->igtk_len,
+                               KEY_FLAG_GROUP_TX_DEFAULT);
        }
 
        /* group privacy / data frames */
@@ -204,7 +206,7 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
                        rsn->mgtk, rsn->mgtk_len);
        wpa_drv_set_key(rsn->wpa_s, wpa_cipher_to_alg(rsn->group_cipher), NULL,
                        rsn->mgtk_key_id, 1, seq, sizeof(seq),
-                       rsn->mgtk, rsn->mgtk_len);
+                       rsn->mgtk, rsn->mgtk_len, KEY_FLAG_GROUP_TX_DEFAULT);
 
        return 0;
 }
index 3f2da34e5bf011a80cf254c5ea59d57183d5c62b..a73282841f7e460e6a42b806bcbbb4f50739d363 100644 (file)
@@ -127,7 +127,8 @@ static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid)
 static int wpa_supplicant_set_key(void *wpa_s, enum wpa_alg alg,
                                  const u8 *addr, int key_idx, int set_tx,
                                  const u8 *seq, size_t seq_len,
-                                 const u8 *key, size_t key_len)
+                                 const u8 *key, size_t key_len,
+                                 enum key_flag key_flag)
 {
        printf("%s - not implemented\n", __func__);
        return -1;
index 0a9e37c3b01cd530d86d810d0763eb343cf80cb0..9f3d6ef600df0250136365dae61bbafa24126a30 100644 (file)
@@ -142,7 +142,10 @@ int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
                set = 1;
                wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
                                i, i == ssid->wep_tx_keyidx, NULL, 0,
-                               ssid->wep_key[i], ssid->wep_key_len[i]);
+                               ssid->wep_key[i], ssid->wep_key_len[i],
+                               i == ssid->wep_tx_keyidx ?
+                               KEY_FLAG_GROUP_RX_TX_DEFAULT :
+                               KEY_FLAG_GROUP_RX_TX);
        }
 
        return set;
@@ -200,7 +203,8 @@ int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
        /* TODO: should actually remember the previously used seq#, both for TX
         * and RX from each STA.. */
 
-       ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
+       ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen,
+                             KEY_FLAG_GROUP_RX_TX_DEFAULT);
        os_memset(key, 0, sizeof(key));
        return ret;
 }
@@ -734,12 +738,12 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
                if (wpa_s->keys_cleared & BIT(i))
                        continue;
                wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
-                               NULL, 0);
+                               NULL, 0, KEY_FLAG_GROUP);
        }
        if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
            !is_zero_ether_addr(addr)) {
                wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
-                               0);
+                               0, KEY_FLAG_PAIRWISE);
                /* MLME-SETPROTECTION.request(None) */
                wpa_drv_mlme_setprotection(
                        wpa_s, addr,
index 240d6109925047beb2c7199907fab24972eb1ba0..9d5d3560798b81aa1aeaf74d50f970343ba63133 100644 (file)
@@ -250,7 +250,9 @@ static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
        }
        return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
                               unicast ? wpa_s->bssid : NULL,
-                              keyidx, unicast, NULL, 0, key, keylen);
+                              keyidx, unicast, NULL, 0, key, keylen,
+                              unicast ? KEY_FLAG_PAIRWISE_RX_TX :
+                              KEY_FLAG_GROUP_RX_TX_DEFAULT);
 }
 
 
@@ -349,7 +351,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
                        "handshake", pmk, pmk_len);
 
        if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
-                           pmk_len)) {
+                           pmk_len, KEY_FLAG_PMK)) {
                wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
        }
 
@@ -500,7 +502,8 @@ static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
 static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg,
                                  const u8 *addr, int key_idx, int set_tx,
                                  const u8 *seq, size_t seq_len,
-                                 const u8 *key, size_t key_len)
+                                 const u8 *key, size_t key_len,
+                                 enum key_flag key_flag)
 {
        struct wpa_supplicant *wpa_s = _wpa_s;
        if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
@@ -525,7 +528,7 @@ static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg,
        }
 #endif /* CONFIG_TESTING_OPTIONS */
        return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
-                              key, key_len);
+                              key, key_len, key_flag);
 }
 
 
@@ -1169,7 +1172,7 @@ static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk,
        if (wpa_s->conf->key_mgmt_offload &&
            (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
                return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0,
-                                      NULL, 0, pmk, pmk_len);
+                                      NULL, 0, pmk, pmk_len, KEY_FLAG_PMK);
        else
                return 0;
 }