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 <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-01-08 22:15:18 +02:00 committed by Jouni Malinen
parent 283be365c3
commit f822546451
13 changed files with 184 additions and 97 deletions

View file

@ -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 *seq, size_t seq_len,
const u8 *key, size_t key_len) const u8 *key, size_t key_len)
{ {
struct wpa_driver_set_key_params params;
if (hapd->driver == NULL || hapd->driver->set_key == NULL) if (hapd->driver == NULL || hapd->driver->set_key == NULL)
return 0; return 0;
return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
key_idx, set_tx, seq, seq_len, key, os_memset(&params, 0, sizeof(params));
key_len); 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, &params);
} }

View file

@ -1524,6 +1524,72 @@ struct wpa_driver_mesh_join_params {
unsigned int flags; 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 * struct wpa_driver_capa - Driver capability information
*/ */
@ -2307,35 +2373,8 @@ struct wpa_driver_ops {
/** /**
* set_key - Configure encryption key * set_key - Configure encryption key
* @ifname: Interface name (for multi-SSID/VLAN support)
* @priv: private driver interface data * @priv: private driver interface data
* @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, * @params: Key parameters
* %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)
*
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
* *
* Configure the given key for the kernel driver. If the driver * 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 * in driver_*.c set_key() implementation, see driver_ndis.c for an
* example on how this can be done. * example on how this can be done.
*/ */
int (*set_key)(const char *ifname, void *priv, enum wpa_alg alg, int (*set_key)(void *priv, struct wpa_driver_set_key_params *params);
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len);
/** /**
* init - Initialize driver interface * init - Initialize driver interface

View file

@ -492,14 +492,18 @@ atheros_del_key(void *priv, const u8 *addr, int key_idx)
} }
static int static int
atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg, atheros_set_key(void *priv, struct wpa_driver_set_key_params *params)
const u8 *addr, int key_idx, int set_tx, const u8 *seq,
size_t seq_len, const u8 *key, size_t key_len)
{ {
struct atheros_driver_data *drv = priv; struct atheros_driver_data *drv = priv;
struct ieee80211req_key wk; struct ieee80211req_key wk;
u_int8_t cipher; u_int8_t cipher;
int ret; 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) if (alg == WPA_ALG_NONE)
return atheros_del_key(drv, addr, key_idx); return atheros_del_key(drv, addr, key_idx);

View file

@ -331,14 +331,20 @@ bsd_ctrl_iface(void *priv, int enable)
} }
static int static int
bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, bsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
size_t seq_len, const u8 *key, size_t key_len)
{ {
struct ieee80211req_key wk; struct ieee80211req_key wk;
#ifdef IEEE80211_KEY_NOREPLAY #ifdef IEEE80211_KEY_NOREPLAY
struct bsd_driver_data *drv = priv; struct bsd_driver_data *drv = priv;
#endif /* IEEE80211_KEY_NOREPLAY */ #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 " 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, "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,

View file

@ -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, static int wpa_driver_hostap_set_key(void *priv,
enum wpa_alg alg, const u8 *addr, struct wpa_driver_set_key_params *params)
int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{ {
struct hostap_driver_data *drv = priv; struct hostap_driver_data *drv = priv;
struct prism2_hostapd_param *param; struct prism2_hostapd_param *param;
u8 *buf; u8 *buf;
size_t blen; size_t blen;
int ret = 0; 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; blen = sizeof(*param) + key_len;
buf = os_zalloc(blen); buf = os_zalloc(blen);

View file

@ -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 static int
wpa_driver_ndis_associate(void *priv, wpa_driver_ndis_associate(void *priv,
struct wpa_driver_associate_params *params) 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.desc = ndis_drv_desc;
wpa_driver_ndis_ops.get_bssid = wpa_driver_ndis_get_bssid; 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.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.init = wpa_driver_ndis_init;
wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit; wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit;
wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate; wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate;

View file

@ -8703,13 +8703,20 @@ nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
#endif /* CONFIG TDLS */ #endif /* CONFIG TDLS */
static int driver_nl80211_set_key(const char *ifname, void *priv, static int driver_nl80211_set_key(void *priv,
enum wpa_alg alg, const u8 *addr, struct wpa_driver_set_key_params *params)
int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{ {
struct i802_bss *bss = priv; 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, 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);
} }

View file

@ -69,12 +69,13 @@ wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa)
static int static int
wpa_driver_openbsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params)
const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
size_t seq_len, const u8 *key, size_t key_len)
{ {
struct openbsd_driver_data *drv = priv; struct openbsd_driver_data *drv = priv;
struct ieee80211_keyavail keyavail; 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) if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN)
return -1; return -1;

View file

@ -205,14 +205,19 @@ wpa_driver_privsep_get_scan_results2(void *priv)
} }
static int wpa_driver_privsep_set_key(const char *ifname, void *priv, static int wpa_driver_privsep_set_key(void *priv,
enum wpa_alg alg, const u8 *addr, struct wpa_driver_set_key_params *params)
int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{ {
struct wpa_driver_privsep_data *drv = priv; struct wpa_driver_privsep_data *drv = priv;
struct privsep_cmd_set_key cmd; 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", wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
__func__, priv, alg, key_idx, set_tx); __func__, priv, alg, key_idx, set_tx);

View file

@ -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 * wpa_driver_wext_set_key - Configure encryption key
* @priv: Pointer to private wext data from wpa_driver_wext_init() * @priv: Pointer to private wext data from wpa_driver_wext_init()
* @priv: Private driver interface data * @params: Key parameters
* @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)
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
* *
* This function uses SIOCSIWENCODEEXT by default, but tries to use * This function uses SIOCSIWENCODEEXT by default, but tries to use
* SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. * 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, static int wpa_driver_wext_set_key(void *priv,
const u8 *addr, int key_idx, struct wpa_driver_set_key_params *params)
int set_tx, const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{ {
struct wpa_driver_wext_data *drv = priv; struct wpa_driver_wext_data *drv = priv;
struct iwreq iwr; struct iwreq iwr;
int ret = 0; 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 " wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
"key_len=%lu", "key_len=%lu",

View file

@ -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_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_freq(void *priv, int freq);
int wpa_driver_wext_set_mode(void *priv, int mode); 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); 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); struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv);

View file

@ -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 *seq, size_t seq_len,
const u8 *key, size_t key_len) const u8 *key, size_t key_len)
{ {
struct wpa_driver_set_key_params params;
os_memset(&params, 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 (alg != WPA_ALG_NONE) {
if (key_idx >= 0 && key_idx <= 6) if (key_idx >= 0 && key_idx <= 6)
wpa_s->keys_cleared &= ~BIT(key_idx); 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; wpa_s->keys_cleared = 0;
} }
if (wpa_s->driver->set_key) { if (wpa_s->driver->set_key) {
return wpa_s->driver->set_key(wpa_s->ifname, wpa_s->drv_priv, return wpa_s->driver->set_key(wpa_s->drv_priv, &params);
alg, addr, key_idx, set_tx,
seq, seq_len, key, key_len);
} }
return -1; return -1;
} }

View file

@ -391,6 +391,7 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface,
{ {
struct privsep_cmd_set_key *params; struct privsep_cmd_set_key *params;
int res; int res;
struct wpa_driver_set_key_params p;
if (iface->drv_priv == NULL || iface->driver->set_key == NULL) if (iface->drv_priv == NULL || iface->driver->set_key == NULL)
return; return;
@ -402,14 +403,18 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface,
params = buf; params = buf;
res = iface->driver->set_key(iface->ifname, iface->drv_priv, os_memset(&p, 0, sizeof(p));
params->alg, p.ifname = iface->ifname;
params->addr, params->key_idx, p.alg = params->alg;
params->set_tx, p.addr = params->addr;
params->seq_len ? params->seq : NULL, p.key_idx = params->key_idx;
params->seq_len, p.set_tx = params->set_tx;
params->key_len ? params->key : NULL, p.seq = params->seq_len ? params->seq : NULL;
params->key_len); 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); wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res);
} }