From f82254645170fa02bb59c4fbc996dba6c173adca Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 8 Jan 2020 22:15:18 +0200 Subject: [PATCH] driver: Move set_key() parameters into a struct This makes it more convenient to add, remove, and modify the parameters without always having to update every single driver_*.c implementation of this callback function. Signed-off-by: Jouni Malinen --- src/ap/ap_drv_ops.c | 18 +++++-- src/drivers/driver.h | 100 ++++++++++++++++++++++++----------- src/drivers/driver_atheros.c | 10 ++-- src/drivers/driver_bsd.c | 12 +++-- src/drivers/driver_hostap.c | 13 +++-- src/drivers/driver_ndis.c | 14 ++++- src/drivers/driver_nl80211.c | 17 ++++-- src/drivers/driver_openbsd.c | 7 +-- src/drivers/driver_privsep.c | 15 ++++-- src/drivers/driver_wext.c | 33 ++++-------- src/drivers/driver_wext.h | 4 -- wpa_supplicant/driver_i.h | 17 ++++-- wpa_supplicant/wpa_priv.c | 21 +++++--- 13 files changed, 184 insertions(+), 97 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 35ecf4102..bb3a6c5c7 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -684,11 +684,23 @@ int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) { + struct wpa_driver_set_key_params params; + 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); + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = ifname; + params.alg = alg; + params.addr = addr; + params.key_idx = key_idx; + params.set_tx = set_tx; + params.seq = seq; + params.seq_len = seq_len; + params.key = key; + params.key_len = key_len; + + return hapd->driver->set_key(hapd->drv_priv, ¶ms); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index f455a2f90..1d18dac31 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1524,6 +1524,72 @@ struct wpa_driver_mesh_join_params { unsigned int flags; }; +struct wpa_driver_set_key_params { + /** + * ifname - Interface name (for multi-SSID/VLAN support) */ + const char *ifname; + + /** + * alg - Encryption algorithm + * + * (%WPA_ALG_NONE, %WPA_ALG_WEP, %WPA_ALG_TKIP, %WPA_ALG_CCMP, + * %WPA_ALG_IGTK, %WPA_ALG_PMK, %WPA_ALG_GCMP, %WPA_ALG_GCMP_256, + * %WPA_ALG_CCMP_256, %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256, + * %WPA_ALG_BIP_CMAC_256); + * %WPA_ALG_NONE clears the key. */ + enum wpa_alg alg; + + /** + * addr - Address of the peer STA + * + * (BSSID of the current AP when setting pairwise key in station mode), + * ff:ff:ff:ff:ff:ff for broadcast keys, %NULL for default keys that + * are used both for broadcast and unicast; when clearing keys, %NULL + * is used to indicate that both the broadcast-only and default key of + * the specified key index is to be cleared */ + const u8 *addr; + + /** + * key_idx - Key index + * + * (0..3), usually 0 for unicast keys; 0..4095 for IGTK */ + int key_idx; + + /** + * set_tx - Configure this key as the default Tx key + * + * Only used when driver does not support separate unicast/individual + * key */ + int set_tx; + + /** + * seq - Sequence number/packet number + * + * seq_len octets, the next packet number to be used for in replay + * protection; configured for Rx keys (in most cases, this is only used + * with broadcast keys and set to zero for unicast keys); %NULL if not + * set */ + const u8 *seq; + + /** + * seq_len - Length of the seq, depends on the algorithm + * + * TKIP: 6 octets, CCMP/GCMP: 6 octets, IGTK: 6 octets */ + size_t seq_len; + + /** + * key - Key buffer + * + * TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key */ + const u8 *key; + + /** + * key_len - Length of the key buffer in octets + * + * WEP: 5 or 13, TKIP: 32, CCMP/GCMP: 16, IGTK: 16 */ + size_t key_len; +}; + /** * struct wpa_driver_capa - Driver capability information */ @@ -2307,35 +2373,8 @@ struct wpa_driver_ops { /** * set_key - Configure encryption key - * @ifname: Interface name (for multi-SSID/VLAN support) * @priv: private driver interface data - * @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, - * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_PMK, - * %WPA_ALG_GCMP, %WPA_ALG_GCMP_256, %WPA_ALG_CCMP_256, - * %WPA_ALG_BIP_GMAC_128, %WPA_ALG_BIP_GMAC_256, - * %WPA_ALG_BIP_CMAC_256); - * %WPA_ALG_NONE clears the key. - * @addr: Address of the peer STA (BSSID of the current AP when setting - * pairwise key in station mode), ff:ff:ff:ff:ff:ff for - * broadcast keys, %NULL for default keys that are used both for - * broadcast and unicast; when clearing keys, %NULL is used to - * indicate that both the broadcast-only and default key of the - * specified key index is to be cleared - * @key_idx: key index (0..3), usually 0 for unicast keys; 0..4095 for - * IGTK - * @set_tx: configure this key as the default Tx key (only used when - * driver does not support separate unicast/individual key - * @seq: sequence number/packet number, seq_len octets, the next - * packet number to be used for in replay protection; configured - * for Rx keys (in most cases, this is only used with broadcast - * keys and set to zero for unicast keys); %NULL if not set - * @seq_len: length of the seq, depends on the algorithm: - * TKIP: 6 octets, CCMP/GCMP: 6 octets, IGTK: 6 octets - * @key: key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, - * 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) - * + * @params: Key parameters * Returns: 0 on success, -1 on failure * * Configure the given key for the kernel driver. If the driver @@ -2356,10 +2395,7 @@ struct wpa_driver_ops { * in driver_*.c set_key() implementation, see driver_ndis.c for an * example on how this can be done. */ - 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); + int (*set_key)(void *priv, struct wpa_driver_set_key_params *params); /** * init - Initialize driver interface diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index de25e4e4e..2014f9db4 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -492,14 +492,18 @@ 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) +atheros_set_key(void *priv, struct wpa_driver_set_key_params *params) { struct atheros_driver_data *drv = priv; struct ieee80211req_key wk; u_int8_t cipher; int ret; + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *key = params->key; + size_t key_len = params->key_len; if (alg == WPA_ALG_NONE) return atheros_del_key(drv, addr, key_idx); diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 8667ee519..a9b5d002d 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -331,14 +331,20 @@ 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) +bsd_set_key(void *priv, struct wpa_driver_set_key_params *params) { struct ieee80211req_key wk; #ifdef IEEE80211_KEY_NOREPLAY struct bsd_driver_data *drv = priv; #endif /* IEEE80211_KEY_NOREPLAY */ + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *seq = params->seq; + size_t seq_len = params->seq_len; + const u8 *key = params->key; + size_t key_len = params->key_len; wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx, diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index dbe7fafc8..cfc52c7f3 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -396,17 +396,20 @@ static int hostapd_ioctl(void *priv, struct prism2_hostapd_param *param, } -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) +static int wpa_driver_hostap_set_key(void *priv, + struct wpa_driver_set_key_params *params) { struct hostap_driver_data *drv = priv; struct prism2_hostapd_param *param; u8 *buf; size_t blen; int ret = 0; + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *key = params->key; + size_t key_len = params->key_len; blen = sizeof(*param) + key_len; buf = os_zalloc(blen); diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index 5b4b9247e..529fc3bc6 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -1033,6 +1033,18 @@ static int wpa_driver_ndis_set_key(const char *ifname, void *priv, } +static int +wpa_driver_ndis_set_key_wrapper(void *priv, + struct wpa_driver_set_key_params *params) +{ + return wpa_driver_ndis_set_key(params->ifname, priv, + params->alg, params->addr, + params->key_idx, params->set_tx, + params->seq, params->seq_len, + params->key, params->key_len); +} + + static int wpa_driver_ndis_associate(void *priv, struct wpa_driver_associate_params *params) @@ -3195,7 +3207,7 @@ void driver_ndis_init_ops(void) wpa_driver_ndis_ops.desc = ndis_drv_desc; wpa_driver_ndis_ops.get_bssid = wpa_driver_ndis_get_bssid; wpa_driver_ndis_ops.get_ssid = wpa_driver_ndis_get_ssid; - wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key; + wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key_wrapper; wpa_driver_ndis_ops.init = wpa_driver_ndis_init; wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit; wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index ddbd4b4bf..35bb750b4 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -8703,13 +8703,20 @@ nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr) #endif /* CONFIG TDLS */ -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) +static int driver_nl80211_set_key(void *priv, + struct wpa_driver_set_key_params *params) { struct i802_bss *bss = priv; + const char *ifname = params->ifname; + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *seq = params->seq; + size_t seq_len = params->seq_len; + const u8 *key = params->key; + size_t key_len = params->key_len; + return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); } diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c index c06e75c0f..e0eede96b 100644 --- a/src/drivers/driver_openbsd.c +++ b/src/drivers/driver_openbsd.c @@ -69,12 +69,13 @@ 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) +wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params) { struct openbsd_driver_data *drv = priv; struct ieee80211_keyavail keyavail; + enum wpa_alg alg = params->alg; + const u8 *key = params->key; + size_t key_len = params->key_len; if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN) return -1; diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c index 55cf61885..807657ebc 100644 --- a/src/drivers/driver_privsep.c +++ b/src/drivers/driver_privsep.c @@ -205,14 +205,19 @@ wpa_driver_privsep_get_scan_results2(void *priv) } -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) +static int wpa_driver_privsep_set_key(void *priv, + struct wpa_driver_set_key_params *params) { struct wpa_driver_privsep_data *drv = priv; struct privsep_cmd_set_key cmd; + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *seq = params->seq; + size_t seq_len = params->seq_len; + const u8 *key = params->key; + size_t key_len = params->key_len; wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d", __func__, priv, alg, key_idx, set_tx); diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 32c297138..776eff72d 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -1803,37 +1803,26 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg, /** * wpa_driver_wext_set_key - Configure encryption key * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @priv: Private driver interface data - * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, - * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key. - * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for - * broadcast/default keys - * @key_idx: key index (0..3), usually 0 for unicast keys - * @set_tx: Configure this key as the default Tx key (only used when - * driver does not support separate unicast/individual key - * @seq: Sequence number/packet number, seq_len octets, the next - * packet number to be used for in replay protection; configured - * for Rx keys (in most cases, this is only used with broadcast - * keys and set to zero for unicast keys) - * @seq_len: Length of the seq, depends on the algorithm: - * TKIP: 6 octets, CCMP: 6 octets - * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, - * 8-byte Rx Mic Key - * @key_len: Length of the key buffer in octets (WEP: 5 or 13, - * TKIP: 32, CCMP: 16) + * @params: Key parameters * Returns: 0 on success, -1 on failure * * This function uses SIOCSIWENCODEEXT by default, but tries to use * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. */ -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) +static int wpa_driver_wext_set_key(void *priv, + struct wpa_driver_set_key_params *params) { struct wpa_driver_wext_data *drv = priv; struct iwreq iwr; int ret = 0; + enum wpa_alg alg = params->alg; + const u8 *addr = params->addr; + int key_idx = params->key_idx; + int set_tx = params->set_tx; + const u8 *seq = params->seq; + size_t seq_len = params->seq_len; + const u8 *key = params->key; + size_t key_len = params->key_len; wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " "key_len=%lu", diff --git a/src/drivers/driver_wext.h b/src/drivers/driver_wext.h index b4b5960a7..6214cdf42 100644 --- a/src/drivers/driver_wext.h +++ b/src/drivers/driver_wext.h @@ -52,10 +52,6 @@ int wpa_driver_wext_get_ssid(void *priv, u8 *ssid); int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len); int wpa_driver_wext_set_freq(void *priv, int freq); 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); 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/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index bc1373bbb..e425ea145 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -149,6 +149,19 @@ static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) { + struct wpa_driver_set_key_params params; + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = wpa_s->ifname; + params.alg = alg; + params.addr = addr; + params.key_idx = key_idx; + params.set_tx = set_tx; + params.seq = seq; + params.seq_len = seq_len; + params.key = key; + params.key_len = key_len; + if (alg != WPA_ALG_NONE) { if (key_idx >= 0 && key_idx <= 6) wpa_s->keys_cleared &= ~BIT(key_idx); @@ -156,9 +169,7 @@ static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, wpa_s->keys_cleared = 0; } 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); + return wpa_s->driver->set_key(wpa_s->drv_priv, ¶ms); } return -1; } diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c index f19735277..f42840610 100644 --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c @@ -391,6 +391,7 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, { struct privsep_cmd_set_key *params; int res; + struct wpa_driver_set_key_params p; if (iface->drv_priv == NULL || iface->driver->set_key == NULL) return; @@ -402,14 +403,18 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, params = buf; - res = iface->driver->set_key(iface->ifname, iface->drv_priv, - params->alg, - params->addr, params->key_idx, - params->set_tx, - params->seq_len ? params->seq : NULL, - params->seq_len, - params->key_len ? params->key : NULL, - params->key_len); + os_memset(&p, 0, sizeof(p)); + p.ifname = iface->ifname; + p.alg = params->alg; + p.addr = params->addr; + p.key_idx = params->key_idx; + p.set_tx = params->set_tx; + p.seq = params->seq_len ? params->seq : NULL; + p.seq_len = params->seq_len; + p.key = params->key_len ? params->key : NULL; + p.key_len = params->key_len; + + res = iface->driver->set_key(iface->drv_priv, &p); wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res); }