Update the nl80211 driver for Extended Key ID support and update the internal API to pass through the needed actions to the drivers. 1) Sync nl80211_copy.h with mac80211-next from 2019-04-18 2) Add key_flag to all needed set_key() to request derivations from normal key install without using it (key_flag is always set to 0) 3) Add key_flags KEY_FLAG_NO_AUTO_TX and KEY_FLAG_SET_TX needed for Extended Key ID support and implement them with the nl80211 driver Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- Differences compared to v1: - Fixed quite some too long lines hostapd/ctrl_iface.c | 33 +++++---- src/ap/ap_drv_ops.c | 4 +- src/ap/ap_drv_ops.h | 2 +- src/ap/hostapd.c | 8 +-- src/ap/ieee802_11.c | 3 +- src/ap/ieee802_1x.c | 7 +- src/ap/wpa_auth.c | 15 ++-- src/ap/wpa_auth.h | 3 +- src/ap/wpa_auth_ft.c | 6 +- src/ap/wpa_auth_glue.c | 4 +- src/common/wpa_common.h | 4 ++ src/drivers/driver.h | 23 +++++-- src/drivers/driver_atheros.c | 2 +- src/drivers/driver_bsd.c | 2 +- src/drivers/driver_hostap.c | 3 +- src/drivers/driver_ndis.c | 2 +- src/drivers/driver_nl80211.c | 111 ++++++++++++++++++++---------- src/drivers/driver_nl80211_capa.c | 4 ++ src/drivers/driver_openbsd.c | 2 +- src/drivers/driver_privsep.c | 3 +- src/drivers/driver_wext.c | 7 +- src/drivers/driver_wext.h | 2 +- src/drivers/nl80211_copy.h | 69 ++++++++++++++++++- src/rsn_supp/tdls.c | 4 +- src/rsn_supp/wpa.c | 17 ++--- src/rsn_supp/wpa.h | 2 +- src/rsn_supp/wpa_ft.c | 7 +- src/rsn_supp/wpa_i.h | 4 +- tests/hwsim/test_ap_ciphers.py | 2 +- wpa_supplicant/ctrl_iface.c | 18 ++--- wpa_supplicant/driver_i.h | 5 +- wpa_supplicant/ibss_rsn.c | 11 +-- wpa_supplicant/mesh_mpm.c | 6 +- wpa_supplicant/mesh_rsn.c | 9 +-- wpa_supplicant/wpa_supplicant.c | 8 +-- wpa_supplicant/wpas_glue.c | 10 +-- 36 files changed, 283 insertions(+), 139 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index e4b16e61a..3d7265b65 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2099,7 +2099,7 @@ 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, 1, NULL, 0, - zero, hapd->last_igtk_len) < 0) + zero, hapd->last_igtk_len, 0) < 0) return -1; /* Set the previously configured key to reset its TSC */ @@ -2108,7 +2108,7 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd) broadcast_ether_addr, hapd->last_igtk_key_idx, 1, NULL, 0, hapd->last_igtk, - hapd->last_igtk_len); + hapd->last_igtk_len, 0); } #endif /* CONFIG_IEEE80211W */ @@ -2124,7 +2124,7 @@ 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, 1, NULL, 0, - zero, hapd->last_gtk_len) < 0) + zero, hapd->last_gtk_len, 0) < 0) return -1; /* Set the previously configured key to reset its TSC */ @@ -2132,7 +2132,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, 1, NULL, 0, - hapd->last_gtk, hapd->last_gtk_len); + hapd->last_gtk, + hapd->last_gtk_len, 0); } sta = ap_get_sta(hapd, addr); @@ -2149,13 +2150,13 @@ 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, 1, NULL, 0, - zero, sta->last_tk_len) < 0) + zero, sta->last_tk_len, 0) < 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, 1, NULL, 0, - sta->last_tk, sta->last_tk_len); + sta->last_tk, sta->last_tk_len, 0); } @@ -2164,11 +2165,11 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd) u8 addr[ETH_ALEN]; const char *pos = cmd; enum wpa_alg alg; - int idx, set_tx; + int idx, set_tx, key_flag; u8 seq[6], key[WPA_TK_MAX_LEN]; size_t key_len; - /* parameters: alg addr idx set_tx seq key */ + /* parameters: alg addr idx set_tx seq key key_flag*/ alg = atoi(pos); pos = os_strchr(pos, ' '); @@ -2201,9 +2202,15 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd) if (hexstr2bin(pos, key, key_len) < 0) return -1; + pos++; + key_flag = atoi(pos); + pos = os_strchr(pos, ' '); + if (!pos) + return -1; + wpa_printf(MSG_INFO, "TESTING: Set key"); return hostapd_drv_set_key(hapd->conf->iface, hapd, alg, addr, idx, - set_tx, seq, 6, key, key_len); + set_tx, seq, 6, key, key_len, key_flag); } @@ -2219,7 +2226,7 @@ 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, 1, NULL, 0, - sta->last_tk, sta->last_tk_len); + sta->last_tk, sta->last_tk_len, 0); } @@ -2243,7 +2250,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, NULL, 0, - NULL, 0); + NULL, 0, 0); } wpa_printf(MSG_INFO, "TESTING: Send M1 to " MACSTR, MAC2STR(sta->addr)); @@ -2273,7 +2280,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, NULL, 0, - NULL, 0); + NULL, 0, 0); } wpa_printf(MSG_INFO, "TESTING: Send M3 to " MACSTR, MAC2STR(sta->addr)); @@ -2303,7 +2310,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, NULL, 0, - NULL, 0); + NULL, 0, 0); } wpa_printf(MSG_INFO, diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 067cf863e..0e81948a1 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -660,13 +660,13 @@ int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd, 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, int key_flag) { if (hapd->driver == NULL || hapd->driver->set_key == NULL) return 0; return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr, key_idx, set_tx, seq, seq_len, key, - key_len); + key_len, key_flag); } diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index de40171e1..bbe44b1b5 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -86,7 +86,7 @@ int hostapd_drv_set_key(const char *ifname, 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, int key_flag); int hostapd_drv_send_mlme(struct hostapd_data *hapd, const void *msg, size_t len, int noack); int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd, diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 20c8e8f5a..020124ddf 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -285,7 +285,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, NULL, 0, NULL, 0)) { + 0, NULL, 0, NULL, 0, 0)) { wpa_printf(MSG_DEBUG, "Failed to clear default " "encryption keys (ifname=%s keyidx=%d)", ifname, i); @@ -296,7 +296,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, NULL, - 0, NULL, 0)) { + 0, NULL, 0, 0)) { wpa_printf(MSG_DEBUG, "Failed to clear " "default mgmt encryption keys " "(ifname=%s keyidx=%d)", ifname, i); @@ -324,7 +324,7 @@ 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, 1, NULL, 0, ssid->wep.key[idx], - ssid->wep.len[idx])) { + ssid->wep.len[idx], 0)) { wpa_printf(MSG_WARNING, "Could not set WEP encryption."); errors++; } @@ -550,7 +550,7 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 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], 0)) { wpa_printf(MSG_WARNING, "Could not set WEP " "encryption."); return -1; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index fde19b526..83d70a102 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -4608,7 +4608,8 @@ 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, i == ssid->wep.idx, NULL, 0, - ssid->wep.key[i], ssid->wep.len[i])) { + ssid->wep.key[i], + ssid->wep.len[i], 0)) { wpa_printf(MSG_WARNING, "Could not set WEP keys for WDS interface; %s", ifname_wds); diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 97f503f75..b6f0d8d5e 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -258,7 +258,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, 1, NULL, 0, ikey, - hapd->conf->individual_wep_key_len)) { + hapd->conf->individual_wep_key_len, + 0)) { wpa_printf(MSG_ERROR, "Could not set individual WEP " "encryption."); } @@ -2060,7 +2061,7 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx) broadcast_ether_addr, eapol->default_wep_key_idx, 1, NULL, 0, eapol->default_wep_key, - hapd->conf->default_wep_key_len)) { + hapd->conf->default_wep_key_len, 0)) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, HOSTAPD_LEVEL_WARNING, "failed to configure a " "new broadcast key"); @@ -2372,7 +2373,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, NULL, 0, - NULL, 0); + NULL, 0, 0); ieee802_1x_rekey(hapd, NULL); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index f2e028c15..d70e2982b 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -136,12 +136,12 @@ 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, int 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); } @@ -1710,7 +1710,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, 0)) wpa_printf(MSG_DEBUG, "RSN: PTK removal from the driver failed"); sm->pairwise_set = FALSE; @@ -2744,7 +2744,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, 0)) { wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver"); return -1; } @@ -3342,7 +3342,7 @@ 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, 0)) { wpa_sta_disconnect(sm->wpa_auth, sm->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); return; @@ -3941,7 +3941,7 @@ 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, 0) < 0) ret = -1; #ifdef CONFIG_IEEE80211W @@ -3955,7 +3955,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, 0) < 0) ret = -1; } #endif /* CONFIG_IEEE80211W */ diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index df1e17a00..783ad6007 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -258,7 +258,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, + int 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); diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index ac16199a6..b95c96264 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2604,12 +2604,12 @@ 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, int 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); } @@ -2642,7 +2642,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, 0)) return; /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 45172c69a..a977b60f2 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -353,7 +353,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, int key_flag) { struct hostapd_data *hapd = ctx; const char *ifname = hapd->conf->iface; @@ -396,7 +396,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, 1, NULL, 0, - key, key_len); + key, key_len, key_flag); } diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index e83d6887a..353ff4017 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -203,6 +203,10 @@ struct wpa_eapol_key { #define FILS_ICK_MAX_LEN 48 #define FILS_FT_MAX_LEN 48 +#define KEY_FLAG_RESERVED BIT(0) /* reserved to replace set_tx */ +#define KEY_FLAG_NO_AUTO_TX BIT(1) +#define KEY_FLAG_SET_TX BIT(2) + /** * struct wpa_ptk - WPA Pairwise Transient Key * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy diff --git a/src/drivers/driver.h b/src/drivers/driver.h index e7c8f318f..4323924c2 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1618,6 +1618,8 @@ struct wpa_driver_capa { #define WPA_DRIVER_FLAGS_FTM_RESPONDER 0x0100000000000000ULL /** Driver support 4-way handshake offload for WPA-Personal */ #define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK 0x0200000000000000ULL +/** Driver supports Extended Key ID */ +#define WPA_DRIVER_FLAGS_EXTENDED_KEY_ID 0x0400000000000000ULL u64 flags; #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ @@ -2244,18 +2246,29 @@ struct wpa_driver_ops { * 8-byte Rx Mic Key * @key_len: length of the key buffer in octets (WEP: 5 or 13, * TKIP: 32, CCMP/GCMP: 16, IGTK: 16) + * @key_flag: Additional flag for key installation. Can only be used + * when the driver supports "Extended Key ID" + * %KEY_FLAG_NO_AUTO_TX: + * Key must only be installed but not yet be used for Tx. + * %KEY_FLAG_SET_TX: + * Key installed with %KEY_FLAG_NO_AUTO_TX is selected as + * new unicast Tx key. Only @ifname, @priv, @addr and @key_idx + * must be set and all other arguments set to zero or NULL. * * Returns: 0 on success, -1 on failure * - * Configure the given key for the kernel driver. If the driver + * When using WEP encryption some special rules apply: If the driver * supports separate individual keys (4 default keys + 1 individual), * addr can be used to determine whether the key is default or * individual. If only 4 keys are supported, the default key with key * index 0 is used as the individual key. STA must be configured to use * it as the default Tx key (set_tx is set) and accept Rx for all the - * key indexes. In most cases, WPA uses only key indexes 1 and 2 for - * broadcast keys, so key index 0 is available for this kind of - * configuration. + * key indexes. (Note: set_tx is being set in many cases without need. + * Sometimes this is detected and needles default key installations are + * suppressed, but often not. The rule seems to be: When set we may have + * to install a default key. When not set we don't have to.) + * TODO: cleanup or better drop set_key and migrate any remaining + * functionality to key_flag. * * Please note that TKIP keys include separate TX and RX MIC keys and * some drivers may expect them in different order than wpa_supplicant @@ -2268,7 +2281,7 @@ struct wpa_driver_ops { int (*set_key)(const char *ifname, void *priv, 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, int key_flag); /** * init - Initialize driver interface diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index 807cd9469..6471e725a 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -500,7 +500,7 @@ atheros_del_key(void *priv, const u8 *addr, int key_idx) static int atheros_set_key(const char *ifname, void *priv, 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) + size_t seq_len, const u8 *key, size_t key_len, int key_flag) { struct atheros_driver_data *drv = priv; struct ieee80211req_key wk; diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 46754968f..d6ff07906 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -333,7 +333,7 @@ bsd_ctrl_iface(void *priv, int enable) static int bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, - size_t seq_len, const u8 *key, size_t key_len) + size_t seq_len, const u8 *key, size_t key_len, int key_flag) { struct ieee80211req_key wk; #ifdef IEEE80211_KEY_NOREPLAY diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index 61b39b197..a7d7b6f01 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -399,7 +399,8 @@ static int wpa_driver_hostap_set_key(const char *ifname, void *priv, 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, + int key_flag) { struct hostap_driver_data *drv = priv; struct prism2_hostapd_param *param; diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index 614c4521e..72ccf02b1 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -932,7 +932,7 @@ static int wpa_driver_ndis_remove_key(struct wpa_driver_ndis_data *drv, static int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv, int pairwise, int key_idx, int set_tx, - const u8 *key, size_t key_len) + const u8 *key, size_t key_len, int key_flag) { NDIS_802_11_WEP *wep; size_t len; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 54fe39000..ff9cc0e61 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3015,11 +3015,13 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, 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, + int key_flag) { struct wpa_driver_nl80211_data *drv = bss->drv; int ifindex; - struct nl_msg *msg = NULL; + struct nl_msg *msg; + struct nl_msg *key_msg; int ret; int tdls = 0; @@ -3029,9 +3031,9 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, ifindex = if_nametoindex(ifname); wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d " - "set_tx=%d seq_len=%lu key_len=%lu", + "set_tx=%d seq_len=%lu key_len=%lu key_flag=%d", __func__, ifindex, ifname, alg, addr, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); + (unsigned long) seq_len, (unsigned long) key_len, key_flag); #ifdef CONFIG_TDLS if (key_idx == -1) { key_idx = 0; @@ -3053,26 +3055,37 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) return nl80211_set_pmk(drv, key, key_len, addr); - if (alg == WPA_ALG_NONE) { + key_msg = nlmsg_alloc(); + if (!key_msg) + return -ENOBUFS; + + if (key_flag & KEY_FLAG_SET_TX) { + msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY); + if (!msg) + goto fail2; + } else if (alg == WPA_ALG_NONE) { msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY); if (!msg) - return -ENOBUFS; + goto fail2; } else { u32 suite; suite = wpa_alg_to_cipher_suite(alg, key_len); if (!suite) - goto fail; + goto fail2; + msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY); - if (!msg || - nla_put(msg, NL80211_ATTR_KEY_DATA, key_len, key) || - nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER, suite)) + if (!msg) + goto fail2; + + if (nla_put(key_msg, NL80211_KEY_DATA, key_len, key) || + nla_put_u32(key_msg, NL80211_KEY_CIPHER, suite)) goto fail; wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len); } - if (seq && seq_len) { - if (nla_put(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq)) + if (seq && seq_len && !(key_flag & KEY_FLAG_SET_TX)) { + if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq)) goto fail; wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len); } @@ -3082,9 +3095,20 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) goto fail; - if (alg != WPA_ALG_WEP && key_idx && !set_tx) { + if (key_flag & (KEY_FLAG_NO_AUTO_TX | KEY_FLAG_SET_TX)) { + wpa_printf(MSG_DEBUG, "Extended Key ID: %s for " + "keyid=%d addr=" MACSTR, + key_flag & KEY_FLAG_NO_AUTO_TX ? + "NO_AUTO_TX" : "SET_TX", + key_idx, MAC2STR(addr)); + if (nla_put_u8(key_msg, NL80211_KEY_MODE, + key_flag & KEY_FLAG_NO_AUTO_TX ? + NL80211_KEY_NO_TX : + NL80211_KEY_SET_TX)) + goto fail; + } else if (alg != WPA_ALG_WEP && key_idx && !set_tx) { wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK"); - if (nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, + if (nla_put_u32(key_msg, NL80211_KEY_TYPE, NL80211_KEYTYPE_GROUP)) goto fail; } @@ -3093,13 +3117,14 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, wpa_printf(MSG_DEBUG, " broadcast key"); - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } - if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx)) + if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) || + nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) goto fail; ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL); @@ -3113,40 +3138,50 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, * If we failed or don't need to set the default TX key (below), * we're done here. */ - if (ret || !set_tx || alg == WPA_ALG_NONE || tdls) + if (ret || !set_tx || key_flag || alg == WPA_ALG_NONE || tdls) return ret; if (is_ap_interface(drv->nlmode) && addr && !is_broadcast_ether_addr(addr)) return ret; + key_msg = nlmsg_alloc(); + if (!key_msg) + return -ENOBUFS; + msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY); - if (!msg || - nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) || - nla_put_flag(msg, (alg == WPA_ALG_IGTK || - alg == WPA_ALG_BIP_GMAC_128 || - alg == WPA_ALG_BIP_GMAC_256 || - alg == WPA_ALG_BIP_CMAC_256) ? - NL80211_ATTR_KEY_DEFAULT_MGMT : - NL80211_ATTR_KEY_DEFAULT)) + if (!msg) + goto fail2; + + if (!key_msg || + nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) || + nla_put_flag(key_msg, (alg == WPA_ALG_IGTK || + alg == WPA_ALG_BIP_GMAC_128 || + alg == WPA_ALG_BIP_GMAC_256 || + alg == WPA_ALG_BIP_CMAC_256) ? + NL80211_KEY_DEFAULT_MGMT : + NL80211_KEY_DEFAULT)) goto fail; if (addr && is_broadcast_ether_addr(addr)) { struct nlattr *types; - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } else if (addr) { struct nlattr *types; - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_UNICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } + if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) + goto fail; + ret = send_and_recv_msgs(drv, msg, NULL, NULL); if (ret == -ENOENT) ret = 0; @@ -3158,6 +3193,9 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, fail: nl80211_nlmsg_clear(msg); nlmsg_free(msg); +fail2: + nl80211_nlmsg_clear(key_msg); + nlmsg_free(key_msg); return -ENOBUFS; } @@ -3468,7 +3506,7 @@ retry: NULL, i, i == params->wep_tx_keyidx, NULL, 0, params->wep_key[i], - params->wep_key_len[i]); + params->wep_key_len[i], 0); if (params->wep_tx_keyidx != i) continue; if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0, @@ -8555,11 +8593,12 @@ static int driver_nl80211_set_key(const char *ifname, void *priv, 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, int key_flag) { struct i802_bss *bss = priv; return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx, - set_tx, seq, seq_len, key, key_len); + set_tx, seq, seq_len, key, key_len, + key_flag); } diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 37eeb5e66..3e05205ea 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -417,6 +417,10 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info, NL80211_EXT_FEATURE_DFS_OFFLOAD)) capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD; + if (ext_feature_isset(ext_features, len, + NL80211_EXT_FEATURE_EXT_KEY_ID)) + capa->flags |= WPA_DRIVER_FLAGS_EXTENDED_KEY_ID; + #ifdef CONFIG_MBO if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) && diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c index c06e75c0f..a6cdf5009 100644 --- a/src/drivers/driver_openbsd.c +++ b/src/drivers/driver_openbsd.c @@ -71,7 +71,7 @@ wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa) static int wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, - size_t seq_len, const u8 *key, size_t key_len) + size_t seq_len, const u8 *key, size_t key_len, int key_flag) { struct openbsd_driver_data *drv = priv; struct ieee80211_keyavail keyavail; diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c index a3f0837e1..977e44c6f 100644 --- a/src/drivers/driver_privsep.c +++ b/src/drivers/driver_privsep.c @@ -209,7 +209,8 @@ static int wpa_driver_privsep_set_key(const char *ifname, void *priv, 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, + int key_flag) { struct wpa_driver_privsep_data *drv = priv; struct privsep_cmd_set_key cmd; diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index f7755cccd..6f63fe44d 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -1712,7 +1712,8 @@ static int wpa_driver_wext_set_key_ext(void *priv, 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, + int key_flag) { struct wpa_driver_wext_data *drv = priv; struct iwreq iwr; @@ -1831,7 +1832,7 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg, int wpa_driver_wext_set_key(const char *ifname, void *priv, 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, int key_flag) { struct wpa_driver_wext_data *drv = priv; struct iwreq iwr; @@ -1843,7 +1844,7 @@ int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg, (unsigned long) seq_len, (unsigned long) key_len); ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx, - seq, seq_len, key, key_len); + seq, seq_len, key, key_len, key_flag); if (ret == 0) return 0; diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h index b4b5960a7..18a8cf2dc 100644 --- a/src/drivers/driver_wext.h +++ b/src/drivers/driver_wext.h @@ -55,7 +55,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode); int wpa_driver_wext_set_key(const char *ifname, void *priv, 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, int key_flag); int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params); struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv); diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h index dd4f86ee2..25f70dd2b 100644 --- a/src/drivers/nl80211_copy.h +++ b/src/drivers/nl80211_copy.h @@ -11,7 +11,7 @@ * Copyright 2008 Jouni Malinen <jouni.malinen@xxxxxxxxxxx> * Copyright 2008 Colin McCabe <colin@xxxxxxxxxxx> * Copyright 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018-2019 Intel Corporation * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1065,6 +1065,11 @@ * indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes * determining the width and type. * + * @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to + * offload OWE processing to user space. This intends to support + * OWE AKM by the host drivers that implement SME but rely + * on the user space for the cryptographic/DH IE processing in AP mode. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1285,6 +1290,8 @@ enum nl80211_commands { NL80211_CMD_NOTIFY_RADAR, + NL80211_CMD_UPDATE_OWE_INFO, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2308,6 +2315,15 @@ enum nl80211_commands { * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime * scheduler. * + * @NL80211_ATTR_STA_TX_POWER_SETTING: Transmit power setting type (u8) for + * station associated with the AP. See &enum nl80211_tx_power_setting for + * possible values. + * @NL80211_ATTR_STA_TX_POWER: Transmit power level (s16) in dBm units. This + * allows to set Tx power for a station. If this attribute is not included, + * the default per-interface tx power setting will be overriding. Driver + * should be picking up the lowest tx power, either tx power per-interface + * or per-station. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2758,6 +2774,8 @@ enum nl80211_attrs { NL80211_ATTR_PEER_MEASUREMENTS, NL80211_ATTR_AIRTIME_WEIGHT, + NL80211_ATTR_STA_TX_POWER_SETTING, + NL80211_ATTR_STA_TX_POWER, /* add attributes here, update the policy in nl80211.c */ @@ -2802,7 +2820,7 @@ enum nl80211_attrs { #define NL80211_MAX_SUPP_RATES 32 #define NL80211_MAX_SUPP_HT_RATES 77 -#define NL80211_MAX_SUPP_REG_RULES 64 +#define NL80211_MAX_SUPP_REG_RULES 128 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 @@ -3139,6 +3157,7 @@ enum nl80211_sta_bss_param { * @NL80211_STA_INFO_TX_DURATION: aggregate PPDU duration for all frames * sent to the station (u64, usec) * @NL80211_STA_INFO_AIRTIME_WEIGHT: current airtime weight for station (u16) + * @NL80211_STA_INFO_AIRTIME_LINK_METRIC: airtime link metric for mesh station * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -3184,6 +3203,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_CONNECTED_TO_GATE, NL80211_STA_INFO_TX_DURATION, NL80211_STA_INFO_AIRTIME_WEIGHT, + NL80211_STA_INFO_AIRTIME_LINK_METRIC, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, @@ -3638,6 +3658,14 @@ enum nl80211_reg_rule_attr { * value as specified by &struct nl80211_bss_select_rssi_adjust. * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching * (this cannot be used together with SSID). + * @NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI: Nested attribute that carries the + * band specific minimum rssi thresholds for the bands defined in + * enum nl80211_band. The minimum rssi threshold value(s32) specific to a + * band shall be encapsulated in attribute with type value equals to one + * of the NL80211_BAND_* defined in enum nl80211_band. For example, the + * minimum rssi threshold value for 2.4GHZ band shall be encapsulated + * within an attribute of type NL80211_BAND_2GHZ. And one or more of such + * attributes will be nested within this attribute. * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter * attribute number currently defined * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use @@ -3650,6 +3678,7 @@ enum nl80211_sched_scan_match_attr { NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST, NL80211_SCHED_SCAN_MATCH_ATTR_BSSID, + NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI, /* keep last */ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, @@ -4134,6 +4163,27 @@ enum nl80211_channel_type { NL80211_CHAN_HT40PLUS }; +/** + * enum nl80211_key_mode - Key mode + * + * @NL80211_KEY_RX_TX: (Default) + * Key can be used for Rx and Tx immediately + * + * The following modes can only be selected for unicast keys and when the + * driver supports @NL80211_EXT_FEATURE_EXT_KEY_ID: + * + * @NL80211_KEY_NO_TX: Only allowed in combination with @NL80211_CMD_NEW_KEY: + * Unicast key can only be used for Rx, Tx not allowed, yet + * @NL80211_KEY_SET_TX: Only allowed in combination with @NL80211_CMD_SET_KEY: + * The unicast key identified by idx and mac is cleared for Tx and becomes + * the preferred Tx key for the station. + */ +enum nl80211_key_mode { + NL80211_KEY_RX_TX, + NL80211_KEY_NO_TX, + NL80211_KEY_SET_TX +}; + /** * enum nl80211_chan_width - channel width definitions * @@ -4377,6 +4427,9 @@ enum nl80211_key_default_types { * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags * attributes, specifying what a key should be set as default as. * See &enum nl80211_key_default_types. + * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode. + * Defaults to @NL80211_KEY_RX_TX. + * * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ @@ -4390,6 +4443,7 @@ enum nl80211_key_attributes { NL80211_KEY_DEFAULT_MGMT, NL80211_KEY_TYPE, NL80211_KEY_DEFAULT_TYPES, + NL80211_KEY_MODE, /* keep last */ __NL80211_KEY_AFTER_LAST, @@ -5335,6 +5389,8 @@ enum nl80211_feature_flags { * able to rekey an in-use key correctly. Userspace must not rekey PTK keys * if this flag is not set. Ignoring this can leak clear text packets and/or * freeze the connection. + * @NL80211_EXT_FEATURE_EXT_KEY_ID: Driver supports "Extended Key ID for + * Individually Addressed Frames" from IEEE802.11-2016. * * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime * fairness for transmitted packets and has enabled airtime fairness @@ -5343,6 +5399,12 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching * (set/del PMKSA operations) in AP mode. * + * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports + * filtering of sched scan results using band specific RSSI thresholds. + * + * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power + * to a station. + * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. */ @@ -5384,6 +5446,9 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, NL80211_EXT_FEATURE_AP_PMKSA_CACHING, + NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, + NL80211_EXT_FEATURE_EXT_KEY_ID, + NL80211_EXT_FEATURE_STA_TX_PWR, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 704c95e68..166bf42c6 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -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, 0) < 0) { wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from " "the driver"); return -1; @@ -228,7 +228,7 @@ 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) { + rsc, sizeof(rsc), peer->tpk.tk, key_len, 0) < 0) { wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " "driver"); return -1; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 9163f61fa..8a5cbe2fe 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -760,7 +760,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, + int key_flag) { int keylen, rsclen; enum wpa_alg alg; @@ -805,7 +806,7 @@ 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) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set PTK to the " "driver (alg=%d keylen=%d bssid=" MACSTR ")", @@ -898,7 +899,7 @@ 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, 0) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set GTK to the driver " "(Group only)"); @@ -907,7 +908,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, 0) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set GTK to " "the driver (alg=%d keylen=%d keyidx=%d)", @@ -1062,7 +1063,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, 0) < 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 @@ -1511,7 +1512,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, 0)) goto failed; } @@ -2086,7 +2087,7 @@ static void wpa_eapol_key_dump(struct wpa_sm *sm, wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16); wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8); - wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8); + wpa_hexdump(MSG_DEBUG, " key_id", key->key_id, 8); wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len); #endif /* CONFIG_NO_STDOUT_DEBUG */ } @@ -4417,7 +4418,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, 0) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid=" MACSTR ")", diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 8903f8e14..7a100fddc 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -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, int 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, diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 7dcb1043b..cb089801e 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -404,7 +404,8 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid) 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) { + sizeof(null_rsc), (u8 *) sm->ptk.tk, + keylen, 0) < 0) { wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver"); return -1; } @@ -748,7 +749,7 @@ 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, 0) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the " "driver."); return -1; @@ -816,7 +817,7 @@ 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, 0) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the " "driver."); os_memset(igtk, 0, sizeof(igtk)); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 0c5955c66..ed8cac767 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -197,11 +197,11 @@ static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, int 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, int 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) diff --git a/tests/hwsim/test_ap_ciphers.py b/tests/hwsim/test_ap_ciphers.py index 59fb651ad..0061d521d 100644 --- a/tests/hwsim/test_ap_ciphers.py +++ b/tests/hwsim/test_ap_ciphers.py @@ -852,7 +852,7 @@ def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev): if "OK" not in hapd.request("RESEND_M3 " + addr): raise Exception("RESEND_M3 failed") - if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s" % (addr, 0, 1, 6*"00", 16*"00")): + if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s 0" % (addr, 0, 1, 6*"00", 16*"00")): raise Exception("SET_KEY failed") time.sleep(0.1) hwsim_utils.test_connectivity(dev[0], hapd, timeout=1, broadcast=False, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 198ac562d..2b6d45665 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5194,17 +5194,17 @@ 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, 0, 0, NULL, 0, NULL, 0, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0, 0); #ifdef CONFIG_IEEE80211W - 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, 4, 0, NULL, 0, NULL, 0, 0); + wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0, 0); #endif /* CONFIG_IEEE80211W */ wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, - 0); + 0, 0); /* MLME-SETPROTECTION.request(None) */ wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, MLME_SETPROTECTION_PROTECT_TYPE_NONE, @@ -9184,13 +9184,13 @@ 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, 0) < 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, 0); } diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 4a9f472e8..d5903e1fd 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -142,7 +142,7 @@ 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, int key_flag) { if (alg != WPA_ALG_NONE) { if (key_idx >= 0 && key_idx <= 6) @@ -153,7 +153,8 @@ static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, if (wpa_s->driver->set_key) { return wpa_s->driver->set_key(wpa_s->ifname, wpa_s->drv_priv, alg, addr, key_idx, set_tx, - seq, seq_len, key, key_len); + seq, seq_len, key, key_len, + key_flag); } return -1; } diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index e96ea65a7..798c60975 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -139,7 +139,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, int key_flag) { struct ibss_rsn_peer *peer = ctx; @@ -166,7 +166,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); } @@ -295,7 +295,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, + int key_flag) { struct ibss_rsn *ibss_rsn = ctx; u8 seq[6]; @@ -334,7 +335,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); } @@ -851,7 +852,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, 0); } if (peer && diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index 9d6ab8da1..a751a1de3 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -844,7 +844,7 @@ 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, 0); wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC", sta->mgtk_rsc, sizeof(sta->mgtk_rsc)); @@ -853,7 +853,7 @@ 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, 0); if (sta->igtk_len) { wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC", @@ -865,7 +865,7 @@ 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, 0); } } diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c index 4b8d6c469..9e7e89634 100644 --- a/wpa_supplicant/mesh_rsn.c +++ b/wpa_supplicant/mesh_rsn.c @@ -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, + int 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, 0); } @@ -199,7 +200,7 @@ 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, 0); } #endif /* CONFIG_IEEE80211W */ @@ -208,7 +209,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, 0); return 0; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 96a3691cf..03e1658cc 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -138,7 +138,7 @@ 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], 0); } return set; @@ -196,7 +196,7 @@ 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, 0); os_memset(key, 0, sizeof(key)); return ret; } @@ -702,12 +702,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, 0); } 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, 0); /* MLME-SETPROTECTION.request(None) */ wpa_drv_mlme_setprotection( wpa_s, addr, diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 449e04acd..0b5da9c9f 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -242,7 +242,7 @@ 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, 0); } @@ -341,7 +341,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, 0)) { wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); } @@ -488,7 +488,7 @@ 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, int key_flag) { struct wpa_supplicant *wpa_s = _wpa_s; if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { @@ -513,7 +513,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); } @@ -1160,7 +1160,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, 0); else return 0; } -- 2.21.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap