Extend the set_key() parameters struct beyond only the driver API. This makes it very trivial to add/use new parameters for set_key() nearly anywhere in the code. Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- This is the "extended" version of converting set_key() funktions to a parameter struct. Instead of translating the new params to the old function parameter names I switched more or less everything to params. This is of course changing quite some code but using only pretty simple transformations. It has some drive-by fixes and unifications: - we zero the ram for structures in three or for different ways and when I added "my" ram zero around one existing I unified these. - I added a few loops, which are much more attractive with the new layout. - And I think you forgot passing through the key_flag in the privsep driver Normally I would now split that into three or four patches and cross check that all set_key calls in all tests are still called with the same arguments. Sounds like you are leaning to not apply this, so I just send you what I have at the moment. I can confirm that I do not have new failed tests with that patch. (Not sure if you like my rename of the driver struct, but since I added a very similar struct for the cases where we have similar but different parameters these two looked too similar with the original name...) Alexander hostapd/ctrl_iface.c | 149 +++++++++++++++++++------------- src/ap/ap_drv_ops.c | 26 +----- src/ap/ap_drv_ops.h | 8 +- src/ap/hostapd.c | 67 +++++++++----- src/ap/ieee802_11.c | 28 ++++-- src/ap/ieee802_1x.c | 55 ++++++++---- src/ap/wpa_auth.c | 78 ++++++++++------- src/ap/wpa_auth.h | 5 +- src/ap/wpa_auth_ft.c | 24 ++--- src/ap/wpa_auth_glue.c | 80 +++++++++-------- src/common/privsep_commands.h | 1 + src/drivers/driver.h | 18 +++- src/drivers/driver_atheros.c | 34 ++++---- src/drivers/driver_bsd.c | 2 +- src/drivers/driver_hostap.c | 19 ++-- src/drivers/driver_ndis.c | 57 ++++++------ src/drivers/driver_nl80211.c | 6 +- src/drivers/driver_openbsd.c | 6 +- src/drivers/driver_privsep.c | 38 ++++---- src/drivers/driver_wext.c | 37 ++++---- src/rsn_supp/tdls.c | 27 ++++-- src/rsn_supp/wpa.c | 143 ++++++++++++++++++------------ src/rsn_supp/wpa.h | 8 +- src/rsn_supp/wpa_ft.c | 92 ++++++++++++-------- src/rsn_supp/wpa_i.h | 10 +-- wpa_supplicant/ctrl_iface.c | 49 ++++++----- wpa_supplicant/driver_i.h | 31 ++----- wpa_supplicant/ibss_rsn.c | 72 ++++++++------- wpa_supplicant/mesh_mpm.c | 60 ++++++++----- wpa_supplicant/mesh_rsn.c | 63 +++++++++----- wpa_supplicant/wpa_priv.c | 3 +- wpa_supplicant/wpa_supplicant.c | 74 ++++++++++------ wpa_supplicant/wpas_glue.c | 82 +++++++++++------- 33 files changed, 829 insertions(+), 623 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 5eef75bf7..11a4140cd 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2135,38 +2135,40 @@ static int hostapd_ctrl_get_fail(struct hostapd_data *hapd, static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd) { struct sta_info *sta; + struct driver_set_key_params params; u8 addr[ETH_ALEN]; u8 zero[WPA_TK_MAX_LEN]; + os_memset(¶ms, 0, sizeof(params)); os_memset(zero, 0, sizeof(zero)); if (hwaddr_aton(cmd, addr)) return -1; + params.ifname = hapd->conf->iface; + params.set_tx = 1; + if (is_broadcast_ether_addr(addr) && os_strstr(cmd, "IGTK")) { if (hapd->last_igtk_alg == WPA_ALG_NONE) return -1; wpa_printf(MSG_INFO, "TESTING: Reset IPN for IGTK"); + params.addr = broadcast_ether_addr; + params.alg = hapd->last_igtk_alg; + params.key_idx = hapd->last_igtk_key_idx; + params.key_len = hapd->last_igtk_len; + params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; + /* First, use a zero key to avoid any possible duplicate key * avoidance in the driver. */ - if (hostapd_drv_set_key(hapd->conf->iface, hapd, - hapd->last_igtk_alg, - broadcast_ether_addr, - hapd->last_igtk_key_idx, 0, 1, NULL, 0, - zero, hapd->last_igtk_len, - KEY_FLAG_GROUP_TX_DEFAULT) < 0) + params.key = zero; + if (hostapd_drv_set_key(hapd, ¶ms) < 0) return -1; /* Set the previously configured key to reset its TSC */ - return hostapd_drv_set_key(hapd->conf->iface, hapd, - hapd->last_igtk_alg, - broadcast_ether_addr, - hapd->last_igtk_key_idx, 0, 1, NULL, - 0, hapd->last_igtk, - hapd->last_igtk_len, - KEY_FLAG_GROUP_TX_DEFAULT); + params.key = hapd->last_igtk; + return hostapd_drv_set_key(hapd, ¶ms); } if (is_broadcast_ether_addr(addr)) { @@ -2175,24 +2177,21 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd) wpa_printf(MSG_INFO, "TESTING: Reset PN for GTK"); + params.addr = broadcast_ether_addr; + params.alg = hapd->last_gtk_alg; + params.key_idx = hapd->last_gtk_key_idx; + params.key_len = hapd->last_gtk_len; + params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; + /* First, use a zero key to avoid any possible duplicate key * avoidance in the driver. */ - if (hostapd_drv_set_key(hapd->conf->iface, hapd, - hapd->last_gtk_alg, - broadcast_ether_addr, - hapd->last_gtk_key_idx, 0, 1, NULL, 0, - zero, hapd->last_gtk_len, - KEY_FLAG_GROUP_TX_DEFAULT) < 0) + params.key = zero; + if (hostapd_drv_set_key(hapd, ¶ms) < 0) return -1; /* Set the previously configured key to reset its TSC */ - return hostapd_drv_set_key(hapd->conf->iface, hapd, - hapd->last_gtk_alg, - broadcast_ether_addr, - hapd->last_gtk_key_idx, 0, 1, NULL, - 0, hapd->last_gtk, - hapd->last_gtk_len, - KEY_FLAG_GROUP_TX_DEFAULT); + params.key = hapd->last_gtk; + return hostapd_drv_set_key(hapd, ¶ms); } sta = ap_get_sta(hapd, addr); @@ -2205,51 +2204,54 @@ static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd) wpa_printf(MSG_INFO, "TESTING: Reset PN for " MACSTR, MAC2STR(sta->addr)); + params.addr = sta->addr; + params.alg = sta->last_tk_alg; + params.key_idx = sta->last_tk_key_idx; + params.key_len = sta->last_tk_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + /* First, use a zero key to avoid any possible duplicate key avoidance * 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, - KEY_FLAG_PAIRWISE_RX_TX) < 0) + params.key = zero; + if (hostapd_drv_set_key(hapd, ¶ms) < 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, - KEY_FLAG_PAIRWISE_RX_TX); + params.key = sta->last_tk; + return hostapd_drv_set_key(hapd, ¶ms); } static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd) { + struct driver_set_key_params params; u8 addr[ETH_ALEN]; const char *pos = cmd; - enum wpa_alg alg; - enum key_flag key_flag; - int idx, set_tx; u8 seq[6], key[WPA_TK_MAX_LEN]; - size_t key_len; + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; /* parameters: alg addr idx set_tx seq key key_flag */ - alg = atoi(pos); + params.alg = atoi(pos); pos = os_strchr(pos, ' '); if (!pos) return -1; pos++; if (hwaddr_aton(pos, addr)) return -1; + params.addr = addr; pos += 17; if (*pos != ' ') return -1; pos++; - idx = atoi(pos); + params.key_idx = atoi(pos); pos = os_strchr(pos, ' '); if (!pos) return -1; pos++; - set_tx = atoi(pos); + params.set_tx = atoi(pos); pos = os_strchr(pos, ' '); if (!pos) return -1; @@ -2259,47 +2261,59 @@ static int hostapd_ctrl_set_key(struct hostapd_data *hapd, const char *cmd) pos += 2 * 6; if (*pos != ' ') return -1; + params.seq = seq; + params.seq_len = 6; pos++; if (!os_strchr(pos, ' ')) return -1; - key_len = (os_strchr(pos, ' ') - pos) / 2; - if (hexstr2bin(pos, key, key_len) < 0) + params.key_len = (os_strchr(pos, ' ') - pos) / 2; + if (hexstr2bin(pos, key, params.key_len) < 0) return -1; - pos += 2 * key_len; + params.key = key; + pos += 2 * params.key_len; if (*pos != ' ') return -1; pos++; - key_flag = atoi(pos); + params.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, 0, - set_tx, seq, 6, key, key_len, key_flag); + return hostapd_drv_set_key(hapd, ¶ms); } static void restore_tk(void *ctx1, void *ctx2) { struct hostapd_data *hapd = ctx1; + struct driver_set_key_params params; struct sta_info *sta = ctx2; + os_memset(¶ms, 0, sizeof(params)); + + params.ifname = hapd->conf->iface; + params.set_tx = 1; + params.addr = sta->addr; + params.alg = sta->last_tk_alg; + params.key_idx = sta->last_tk_key_idx; + params.key = sta->last_tk; + params.key_len = sta->last_tk_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + wpa_printf(MSG_INFO, "TESTING: Restore TK for " MACSTR, MAC2STR(sta->addr)); /* This does not really restore the TSC properly, so this will result * in replay protection issues for now since there is no clean way of * 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, - KEY_FLAG_PAIRWISE_RX_TX); + hostapd_drv_set_key(hapd, ¶ms); } static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd) { + struct driver_set_key_params params; struct sta_info *sta; u8 addr[ETH_ALEN]; int plain = os_strstr(cmd, "plaintext") != NULL; @@ -2316,9 +2330,14 @@ static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd) if (plain) { wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR, 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, KEY_FLAG_PAIRWISE); + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.addr = sta->addr; + params.key_idx = sta->last_tk_key_idx; + params.key_flag = KEY_FLAG_PAIRWISE; + + hostapd_drv_set_key(hapd, ¶ms); } wpa_printf(MSG_INFO, "TESTING: Send M1 to " MACSTR, MAC2STR(sta->addr)); @@ -2330,6 +2349,7 @@ static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd) static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd) { + struct driver_set_key_params params; struct sta_info *sta; u8 addr[ETH_ALEN]; int plain = os_strstr(cmd, "plaintext") != NULL; @@ -2346,9 +2366,13 @@ static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd) if (plain) { wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR, 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, KEY_FLAG_PAIRWISE); + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.addr = sta->addr; + params.key_idx = sta->last_tk_key_idx; + params.key_flag = KEY_FLAG_PAIRWISE; + hostapd_drv_set_key(hapd, ¶ms); } wpa_printf(MSG_INFO, "TESTING: Send M3 to " MACSTR, MAC2STR(sta->addr)); @@ -2360,6 +2384,7 @@ static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd) static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd, const char *cmd) { + struct driver_set_key_params params; struct sta_info *sta; u8 addr[ETH_ALEN]; int plain = os_strstr(cmd, "plaintext") != NULL; @@ -2376,9 +2401,13 @@ static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd, if (plain) { wpa_printf(MSG_INFO, "TESTING: Clear TK for " MACSTR, 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, KEY_FLAG_PAIRWISE); + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.addr = sta->addr; + params.key_idx = sta->last_tk_key_idx; + params.key_flag = KEY_FLAG_PAIRWISE; + hostapd_drv_set_key(hapd, ¶ms); } wpa_printf(MSG_INFO, diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index c217d9b24..f367f8571 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -677,32 +677,12 @@ int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start, return -1; } - -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, enum key_flag key_flag) +int hostapd_drv_set_key(struct hostapd_data *hapd, + struct driver_set_key_params *params) { - struct wpa_driver_set_key_params params; - if (hapd->driver == NULL || hapd->driver->set_key == NULL) return 0; - - 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; - params.vlan_id = vlan_id; - params.key_flag = key_flag; - - return hapd->driver->set_key(hapd->drv_priv, ¶ms); + return hapd->driver->set_key(hapd->drv_priv, params); } diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 56d1ad862..a61cc972e 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -86,12 +86,8 @@ struct wpa_scan_results * hostapd_driver_get_scan_results( struct hostapd_data *hapd); int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start, int duration); -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, enum key_flag key_flag); +int hostapd_drv_set_key(struct hostapd_data *hapd, + struct driver_set_key_params *params); 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, diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index b87663fe9..8f0aa739d 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -287,13 +287,19 @@ int hostapd_reload_config(struct hostapd_iface *iface) static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, const char *ifname) { + struct driver_set_key_params params; int i; if (!ifname || !hapd->drv_priv) return; + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = ifname; + params.key_flag = KEY_FLAG_GROUP; + 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, KEY_FLAG_GROUP)) { + params.key_idx = i; + if (hostapd_drv_set_key(hapd, ¶ms)) { wpa_printf(MSG_DEBUG, "Failed to clear default " "encryption keys (ifname=%s keyidx=%d)", ifname, i); @@ -301,9 +307,8 @@ static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, } if (hapd->conf->ieee80211w) { 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, KEY_FLAG_GROUP)) { + params.key_idx = i; + if (hostapd_drv_set_key(hapd, ¶ms)) { wpa_printf(MSG_DEBUG, "Failed to clear " "default mgmt encryption keys " "(ifname=%s keyidx=%d)", ifname, i); @@ -322,16 +327,23 @@ static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd) static int hostapd_broadcast_wep_set(struct hostapd_data *hapd) { - int errors = 0, idx; struct hostapd_ssid *ssid = &hapd->conf->ssid; + struct driver_set_key_params params; + int errors = 0; + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.set_tx = 1; + + params.addr = broadcast_ether_addr; + params.alg = WPA_ALG_WEP; + params.key_idx = ssid->wep.idx; + params.key = ssid->wep.key[params.key_idx]; + params.key_len = ssid->wep.len[params.key_idx]; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; - idx = ssid->wep.idx; if (ssid->wep.default_len && - 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], - KEY_FLAG_GROUP_RX_TX_DEFAULT)) { + hostapd_drv_set_key(hapd, ¶ms)) { wpa_printf(MSG_WARNING, "Could not set WEP encryption."); errors++; } @@ -537,7 +549,11 @@ static void hostapd_clear_wep(struct hostapd_data *hapd) static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) { - int i; + struct driver_set_key_params params; + + os_memset(¶ms, 0, sizeof(params)); + params.ifname = iface; + params.alg = WPA_ALG_WEP; hostapd_broadcast_wep_set(hapd); @@ -551,22 +567,25 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) * set authentication algorithms for static WEP. */ hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs); + for (; params.key_idx < 4; params.key_idx++) { + if (params.key_idx == hapd->conf->ssid.wep.idx) { + params.set_tx = 1; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; + } else { + params.set_tx = 0; + params.key_flag = KEY_FLAG_GROUP_RX_TX; + } + params.key = hapd->conf->ssid.wep.key[params.key_idx]; + params.key_len = hapd->conf->ssid.wep.len[params.key_idx]; - for (i = 0; i < 4; i++) { - if (hapd->conf->ssid.wep.key[i] && - 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], - i == hapd->conf->ssid.wep.idx ? - KEY_FLAG_GROUP_RX_TX_DEFAULT : - KEY_FLAG_GROUP_RX_TX)) { + if (hapd->conf->ssid.wep.key[params.key_idx] && + hostapd_drv_set_key(hapd, ¶ms)) { wpa_printf(MSG_WARNING, "Could not set WEP " "encryption."); return -1; } - if (hapd->conf->ssid.wep.key[i] && - i == hapd->conf->ssid.wep.idx) + if (hapd->conf->ssid.wep.key[params.key_idx] && + params.key_idx == hapd->conf->ssid.wep.idx) hostapd_set_privacy(hapd, 1); } diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index cd6107794..38d23fd87 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -4902,20 +4902,30 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd, struct sta_info *sta, char *ifname_wds) { - int i; + struct driver_set_key_params params; struct hostapd_ssid *ssid = &hapd->conf->ssid; if (hapd->conf->ieee802_1x || hapd->conf->wpa) return; - for (i = 0; i < 4; i++) { - 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], - i == ssid->wep.idx ? - KEY_FLAG_GROUP_RX_TX_DEFAULT : - KEY_FLAG_GROUP_RX_TX)) { + os_memset(¶ms, 0, sizeof(params)); + params.ifname = ifname_wds; + params.alg = WPA_ALG_WEP; + + for (; params.key_idx < 4; params.key_idx++) { + if (params.key_idx == ssid->wep.idx) { + params.set_tx = 1; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; + } else { + params.set_tx = 0; + params.key_flag = KEY_FLAG_GROUP_RX_TX; + } + params.key = ssid->wep.key[params.key_idx]; + params.key_len = ssid->wep.len[params.key_idx]; + + + if (ssid->wep.key[params.key_idx] && + hostapd_drv_set_key(hapd, ¶ms)) { 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 001b26109..1bacf49c9 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -263,35 +263,43 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta) } if (hapd->conf->individual_wep_key_len > 0) { + struct driver_set_key_params params; u8 *ikey; - ikey = os_malloc(hapd->conf->individual_wep_key_len); + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.set_tx = 1; + params.addr = sta->addr; + params.alg = WPA_ALG_WEP; + params.key_len = hapd->conf->individual_wep_key_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + + ikey = os_malloc(params.key_len); if (!ikey || - random_get_bytes(ikey, hapd->conf->individual_wep_key_len)) + random_get_bytes(ikey, params.key_len)) { wpa_printf(MSG_ERROR, "Could not generate random individual WEP key"); os_free(ikey); return; } + params.key = ikey; wpa_hexdump_key(MSG_DEBUG, "Individual WEP key", - ikey, hapd->conf->individual_wep_key_len); + params.key, params.key_len); ieee802_1x_tx_key_one(hapd, sta, 0, 0, ikey, - hapd->conf->individual_wep_key_len); + params.key_len); /* TODO: set encryption in TX callback, i.e., only after 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, - KEY_FLAG_PAIRWISE_RX_TX)) { + if (hostapd_drv_set_key(hapd, ¶ms)) { wpa_printf(MSG_ERROR, "Could not set individual WEP encryption"); } os_free(ikey); + params.key = NULL; } } @@ -2153,6 +2161,7 @@ static int ieee802_1x_sta_key_available(struct hostapd_data *hapd, static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx) { + struct driver_set_key_params params; struct hostapd_data *hapd = eloop_ctx; struct eapol_authenticator *eapol = hapd->eapol_auth; @@ -2174,14 +2183,20 @@ static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx) return; } + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.set_tx = 1; + + params.addr = broadcast_ether_addr; + params.alg = WPA_ALG_WEP; + params.key_idx = eapol->default_wep_key_idx; + params.key = eapol->default_wep_key; + params.key_len = hapd->conf->default_wep_key_len; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; + /* TODO: Could setup key for RX here, but change default TX keyid only * after new broadcast key has been sent to all stations. */ - if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP, - broadcast_ether_addr, - eapol->default_wep_key_idx, 0, 1, NULL, 0, - eapol->default_wep_key, - hapd->conf->default_wep_key_len, - KEY_FLAG_GROUP_RX_TX_DEFAULT)) { + if (hostapd_drv_set_key(hapd, ¶ms)) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X, HOSTAPD_LEVEL_WARNING, "failed to configure a new broadcast key"); @@ -2422,7 +2437,7 @@ static int ieee802_1x_erp_add_key(void *ctx, struct eap_server_erp_key *erp) int ieee802_1x_init(struct hostapd_data *hapd) { - int i; + struct driver_set_key_params params; struct eapol_auth_config conf; struct eapol_auth_cb cb; @@ -2469,11 +2484,13 @@ int ieee802_1x_init(struct hostapd_data *hapd) return -1; #endif /* CONFIG_NO_RADIUS */ + os_memset(¶ms, 0, sizeof(params)); + params.ifname = hapd->conf->iface; + params.key_flag = KEY_FLAG_GROUP; + if (hapd->conf->default_wep_key_len) { - 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, KEY_FLAG_GROUP_RX_TX); + for (; params.key_idx < 4; params.key_idx++) + hostapd_drv_set_key(hapd, ¶ms); ieee802_1x_rekey(hapd, NULL); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 423528d12..0536e45cd 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -134,15 +134,11 @@ 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, - enum key_flag key_flag) + struct wpa_set_key_params *wpa_params) { 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_flag); + return wpa_auth->cb->set_key(wpa_auth->cb_ctx, wpa_params); } @@ -1736,10 +1732,17 @@ static int wpa_verify_key_mic(int akmp, size_t pmk_len, struct wpa_ptk *PTK, void wpa_remove_ptk(struct wpa_state_machine *sm) { + struct wpa_set_key_params wpa_params; + sm->PTK_valid = FALSE; + os_memset(&wpa_params, 0, sizeof(wpa_params)); 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, KEY_FLAG_PAIRWISE)) + + wpa_params.alg = WPA_ALG_NONE; + wpa_params.addr = sm->addr; + wpa_params.key_flag = KEY_FLAG_PAIRWISE; + + if (wpa_auth_set_key(sm->wpa_auth, &wpa_params)) wpa_printf(MSG_DEBUG, "RSN: PTK removal from the driver failed"); sm->pairwise_set = FALSE; @@ -2755,8 +2758,7 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm, int fils_set_tk(struct wpa_state_machine *sm) { - enum wpa_alg alg; - int klen; + struct wpa_set_key_params wpa_params; if (!sm || !sm->PTK_valid) { wpa_printf(MSG_DEBUG, "FILS: No valid PTK available to set TK"); @@ -2767,12 +2769,15 @@ int fils_set_tk(struct wpa_state_machine *sm) return -1; } - alg = wpa_cipher_to_alg(sm->pairwise); - klen = wpa_cipher_key_len(sm->pairwise); + os_memset(&wpa_params, 0, sizeof(wpa_params)); + wpa_params.alg = wpa_cipher_to_alg(sm->pairwise); + wpa_params.addr = sm->addr; + wpa_params.key = sm->PTK.tk; + wpa_params.key_len = wpa_cipher_key_len(sm->pairwise); + wpa_params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; 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, KEY_FLAG_PAIRWISE_RX_TX)) { + if (wpa_auth_set_key(sm->wpa_auth, &wpa_params)) { wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver"); return -1; } @@ -3394,11 +3399,15 @@ SM_STATE(WPA_PTK, PTKINITDONE) SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk); sm->EAPOLKeyReceived = FALSE; if (sm->Pair) { - 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, - KEY_FLAG_PAIRWISE_RX_TX)) { + struct wpa_set_key_params wpa_params; + + os_memset(&wpa_params, 0, sizeof(wpa_params)); + wpa_params.alg = wpa_cipher_to_alg(sm->pairwise); + wpa_params.addr = sm->addr; + wpa_params.key = sm->PTK.tk; + wpa_params.key_len = wpa_cipher_key_len(sm->pairwise); + wpa_params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + if (wpa_auth_set_key(sm->wpa_auth, &wpa_params)) { wpa_sta_disconnect(sm->wpa_auth, sm->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); return; @@ -3985,27 +3994,30 @@ static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth, static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth, struct wpa_group *group) { + struct wpa_set_key_params wpa_params; int ret = 0; - 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, - KEY_FLAG_GROUP_TX_DEFAULT) < 0) + os_memset(&wpa_params, 0, sizeof(wpa_params)); + wpa_params.vlan_id = group->vlan_id; + wpa_params.alg = wpa_cipher_to_alg(wpa_auth->conf.wpa_group); + wpa_params.key_idx = group->GN; + wpa_params.addr = broadcast_ether_addr; + wpa_params.key = group->GTK[group->GN - 1]; + wpa_params.key_len = group->GTK_len; + wpa_params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; + + if (wpa_auth_set_key(wpa_auth, &wpa_params) < 0) ret = -1; if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) { - enum wpa_alg alg; - size_t len; - - alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher); - len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); + wpa_params.alg = wpa_cipher_to_alg(wpa_auth->conf.group_mgmt_cipher); + wpa_params.key_idx = group->GN_igtk; + wpa_params.key = group->IGTK[group->GN_igtk - 4]; + wpa_params.key_len = wpa_cipher_key_len(wpa_auth->conf.group_mgmt_cipher); + wpa_params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; 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, - KEY_FLAG_GROUP_TX_DEFAULT) < 0) + wpa_auth_set_key(wpa_auth, &wpa_params) < 0) ret = -1; } diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 0b4b7297c..5b8f5a1c7 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -146,6 +146,7 @@ struct rsn_pmksa_cache_entry; struct eapol_state_machine; struct ft_remote_seq; struct wpa_channel_info; +struct wpa_set_key_params; struct ft_remote_r0kh { @@ -262,9 +263,7 @@ struct wpa_auth_callbacks { const u8 *prev_psk, size_t *psk_len, 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, - enum key_flag key_flag); + int (*set_key)(void *ctx, struct wpa_set_key_params *wpa_params); 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 462876195..b10c773f8 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2620,26 +2620,19 @@ 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, - enum key_flag key_flag) + struct wpa_set_key_params *wpa_params) { 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_flag); + return wpa_auth->cb->set_key(wpa_auth->cb_ctx, wpa_params); } void wpa_ft_install_ptk(struct wpa_state_machine *sm) { - enum wpa_alg alg; - int klen; + struct wpa_set_key_params wpa_params; /* MLME-SETKEYS.request(PTK) */ - alg = wpa_cipher_to_alg(sm->pairwise); - klen = wpa_cipher_key_len(sm->pairwise); if (!wpa_cipher_valid_pairwise(sm->pairwise)) { wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip " "PTK configuration", sm->pairwise); @@ -2660,8 +2653,15 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) * again after association to get the PTK configured, but that could be * optimized by adding the STA entry earlier. */ - if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, - sm->PTK.tk, klen, KEY_FLAG_PAIRWISE_RX_TX)) + + os_memset(&wpa_params, 0, sizeof(wpa_params)); + wpa_params.alg = wpa_cipher_to_alg(sm->pairwise); + wpa_params.addr = sm->addr; + wpa_params.key = sm->PTK.tk; + wpa_params.key_len = wpa_cipher_key_len(sm->pairwise); + wpa_params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + + if (wpa_auth_set_key(sm->wpa_auth, &wpa_params)) 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 e64304636..8694d296b 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -376,54 +376,62 @@ 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, enum key_flag key_flag) +static int hostapd_wpa_auth_set_key(void *ctx, + struct wpa_set_key_params *wpa_params) { + struct driver_set_key_params params; struct hostapd_data *hapd = ctx; - const char *ifname = hapd->conf->iface; - - if (vlan_id > 0) { - ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id); - if (!ifname) { - if (!(hapd->iface->drv_flags & - WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) - return -1; - ifname = hapd->conf->iface; - } + + os_memset(¶ms, 0, sizeof(params)); + + if (wpa_params->vlan_id > 0) { + params.ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, + wpa_params->vlan_id); + if (params.ifname == NULL) + return -1; + } else { + params.ifname = hapd->conf->iface; } + params.set_tx = 1; + params.addr = wpa_params->addr; + params.alg = wpa_params->alg; + params.key = wpa_params->key; + params.key_len = wpa_params->key_len; + params.key_idx = wpa_params->key_idx; + params.key_flag = wpa_params->key_flag; #ifdef CONFIG_TESTING_OPTIONS - if (addr && !is_broadcast_ether_addr(addr)) { + if (wpa_params->addr && !is_broadcast_ether_addr(wpa_params->addr)) { struct sta_info *sta; - sta = ap_get_sta(hapd, addr); + sta = ap_get_sta(hapd, wpa_params->addr); if (sta) { - sta->last_tk_alg = alg; - sta->last_tk_key_idx = idx; - if (key) - os_memcpy(sta->last_tk, key, key_len); - sta->last_tk_len = key_len; + sta->last_tk_alg = wpa_params->alg; + sta->last_tk_key_idx = wpa_params->key_idx; + if (wpa_params->key) + os_memcpy(sta->last_tk, wpa_params->key, + wpa_params->key_len); + sta->last_tk_len = wpa_params->key_len; } - } else if (alg == WPA_ALG_IGTK || - alg == WPA_ALG_BIP_GMAC_128 || - alg == WPA_ALG_BIP_GMAC_256 || - alg == WPA_ALG_BIP_CMAC_256) { - hapd->last_igtk_alg = alg; - hapd->last_igtk_key_idx = idx; - if (key) - os_memcpy(hapd->last_igtk, key, key_len); - hapd->last_igtk_len = key_len; + } else if (wpa_params->alg == WPA_ALG_IGTK || + wpa_params->alg == WPA_ALG_BIP_GMAC_128 || + wpa_params->alg == WPA_ALG_BIP_GMAC_256 || + wpa_params->alg == WPA_ALG_BIP_CMAC_256) { + hapd->last_igtk_alg = wpa_params->alg; + hapd->last_igtk_key_idx = wpa_params->key_idx; + if (wpa_params->key) + os_memcpy(hapd->last_igtk, wpa_params->key, + wpa_params->key_len); + hapd->last_igtk_len = wpa_params->key_len; } else { - hapd->last_gtk_alg = alg; - hapd->last_gtk_key_idx = idx; - if (key) - os_memcpy(hapd->last_gtk, key, key_len); - hapd->last_gtk_len = key_len; + hapd->last_gtk_alg = wpa_params->alg; + hapd->last_gtk_key_idx = wpa_params->key_idx; + if (wpa_params->key) + os_memcpy(hapd->last_gtk, wpa_params->key, wpa_params->key_len); + hapd->last_gtk_len = wpa_params->key_len; } #endif /* CONFIG_TESTING_OPTIONS */ - return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, vlan_id, 1, - NULL, 0, key, key_len, key_flag); + return hostapd_drv_set_key(hapd, ¶ms); } diff --git a/src/common/privsep_commands.h b/src/common/privsep_commands.h index b85c6c347..d2c4bbd5e 100644 --- a/src/common/privsep_commands.h +++ b/src/common/privsep_commands.h @@ -82,6 +82,7 @@ struct privsep_cmd_set_key { size_t seq_len; u8 key[32]; size_t key_len; + enum key_flag key_flag; }; enum privsep_event { diff --git a/src/drivers/driver.h b/src/drivers/driver.h index c37dd2fc9..1e4179e1a 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1182,6 +1182,20 @@ struct wpa_driver_associate_params { size_t fils_erp_rrk_len; }; +/** + * struct wpa_set_key_params - WPA set_key params + * Data for struct wpa_auth_callbacks::set_key(). + */ +struct wpa_set_key_params { + int vlan_id; + enum wpa_alg alg; + const u8 *addr; + int key_idx; + u8 *key; + size_t key_len; + enum key_flag key_flag; +}; + enum hide_ssid { NO_SSID_HIDING, HIDDEN_SSID_ZERO_LEN, @@ -1524,7 +1538,7 @@ struct wpa_driver_mesh_join_params { unsigned int flags; }; -struct wpa_driver_set_key_params { +struct driver_set_key_params { /** * ifname - Interface name (for multi-SSID/VLAN support) */ const char *ifname; @@ -2446,7 +2460,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)(void *priv, struct wpa_driver_set_key_params *params); + int (*set_key)(void *priv, struct driver_set_key_params *params); /** * init - Initialize driver interface diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index 2014f9db4..b207aec4a 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -492,7 +492,7 @@ atheros_del_key(void *priv, const u8 *addr, int key_idx) } static int -atheros_set_key(void *priv, struct wpa_driver_set_key_params *params) +atheros_set_key(void *priv, struct driver_set_key_params *params) { struct atheros_driver_data *drv = priv; struct ieee80211req_key wk; @@ -505,13 +505,14 @@ atheros_set_key(void *priv, struct wpa_driver_set_key_params *params) 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); + if (params->alg == WPA_ALG_NONE) + return atheros_del_key(drv, params->addr, params->key_idx); wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", - __func__, alg, ether_sprintf(addr), key_idx); + __func__, params->alg, ether_sprintf(params->addr), + params->key_idx); - switch (alg) { + switch (params->alg) { case WPA_ALG_WEP: cipher = IEEE80211_CIPHER_WEP; break; @@ -548,37 +549,38 @@ atheros_set_key(void *priv, struct wpa_driver_set_key_params *params) #endif /* ATH_GCM_SUPPORT */ default: wpa_printf(MSG_INFO, "%s: unknown/unsupported algorithm %d", - __func__, alg); + __func__, params->alg); return -1; } - if (key_len > sizeof(wk.ik_keydata)) { + if (params->key_len > sizeof(wk.ik_keydata)) { wpa_printf(MSG_INFO, "%s: key length %lu too big", __func__, - (unsigned long) key_len); + (unsigned long) params->key_len); return -3; } os_memset(&wk, 0, sizeof(wk)); wk.ik_type = cipher; wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; - if (addr == NULL || is_broadcast_ether_addr(addr)) { + if (params->addr == NULL || is_broadcast_ether_addr(params->addr)) { os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); - wk.ik_keyix = key_idx; - if (set_tx) + wk.ik_keyix = params->key_idx; + if (params->set_tx) wk.ik_flags |= IEEE80211_KEY_DEFAULT; } else { - os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); + os_memcpy(wk.ik_macaddr, params->addr, IEEE80211_ADDR_LEN); wk.ik_keyix = IEEE80211_KEYIX_NONE; } - wk.ik_keylen = key_len; - os_memcpy(wk.ik_keydata, key, key_len); + wk.ik_keylen = params->key_len; + os_memcpy(wk.ik_keydata, params->key, params->key_len); ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); if (ret < 0) { wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" " key_idx %d alg %d key_len %lu set_tx %d)", - __func__, ether_sprintf(wk.ik_macaddr), key_idx, - alg, (unsigned long) key_len, set_tx); + __func__, ether_sprintf(wk.ik_macaddr), + params->key_idx, params->alg, (unsigned long) + params->key_len, params->set_tx); } return ret; diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index a9b5d002d..f4dbe7755 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -331,7 +331,7 @@ bsd_ctrl_iface(void *priv, int enable) } static int -bsd_set_key(void *priv, struct wpa_driver_set_key_params *params) +bsd_set_key(void *priv, struct driver_set_key_params *params) { struct ieee80211req_key wk; #ifdef IEEE80211_KEY_NOREPLAY diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index cfc52c7f3..31f9fa447 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -397,7 +397,7 @@ static int hostapd_ioctl(void *priv, struct prism2_hostapd_param *param, static int wpa_driver_hostap_set_key(void *priv, - struct wpa_driver_set_key_params *params) + struct driver_set_key_params *params) { struct hostap_driver_data *drv = priv; struct prism2_hostapd_param *param; @@ -411,18 +411,18 @@ static int wpa_driver_hostap_set_key(void *priv, const u8 *key = params->key; size_t key_len = params->key_len; - blen = sizeof(*param) + key_len; + blen = sizeof(*param) + params->key_len; buf = os_zalloc(blen); if (buf == NULL) return -1; param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_SET_ENCRYPTION; - if (addr == NULL) + if (params->addr == NULL) memset(param->sta_addr, 0xff, ETH_ALEN); else - memcpy(param->sta_addr, addr, ETH_ALEN); - switch (alg) { + memcpy(param->sta_addr, params->addr, ETH_ALEN); + switch (params->alg) { case WPA_ALG_NONE: os_strlcpy((char *) param->u.crypt.alg, "NONE", HOSTAP_CRYPT_ALG_NAME_LEN); @@ -443,10 +443,11 @@ static int wpa_driver_hostap_set_key(void *priv, os_free(buf); return -1; } - param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; - param->u.crypt.idx = key_idx; - param->u.crypt.key_len = key_len; - memcpy((u8 *) (param + 1), key, key_len); + param->u.crypt.flags = params->set_tx ? + HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; + param->u.crypt.idx = params->key_idx; + param->u.crypt.key_len = params->key_len; + memcpy((u8 *) (param + 1), params->key, params->key_len); if (hostapd_ioctl(drv, param, blen)) { printf("Failed to set encryption.\n"); diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index 529fc3bc6..db99522d7 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -963,11 +963,8 @@ static int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv, } -static int wpa_driver_ndis_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_ndis_set_key(void *priv, + struct driver_set_key_params *params) { struct wpa_driver_ndis_data *drv = priv; size_t len, i; @@ -975,7 +972,7 @@ static int wpa_driver_ndis_set_key(const char *ifname, void *priv, int res, pairwise; u8 bssid[ETH_ALEN]; - if (addr == NULL || is_broadcast_ether_addr(addr)) { + if (params->addr == NULL || is_broadcast_ether_addr(params->addr)) { /* Group Key */ pairwise = 0; if (wpa_driver_ndis_get_bssid(drv, bssid) < 0) @@ -983,45 +980,47 @@ static int wpa_driver_ndis_set_key(const char *ifname, void *priv, } else { /* Pairwise Key */ pairwise = 1; - os_memcpy(bssid, addr, ETH_ALEN); + os_memcpy(bssid, params->addr, ETH_ALEN); } - if (alg == WPA_ALG_NONE || key_len == 0) { - return wpa_driver_ndis_remove_key(drv, key_idx, addr, bssid, + if (params->alg == WPA_ALG_NONE || params->key_len == 0) { + return wpa_driver_ndis_remove_key(drv, params->key_idx, + params->addr, bssid, pairwise); } - if (alg == WPA_ALG_WEP) { - return wpa_driver_ndis_add_wep(drv, pairwise, key_idx, set_tx, - key, key_len); + if (params->alg == WPA_ALG_WEP) { + return wpa_driver_ndis_add_wep(drv, pairwise, params->key_idx, + params->set_tx, params->key, + params->key_len); } - len = 12 + 6 + 6 + 8 + key_len; + len = 12 + 6 + 6 + 8 + params->key_len; nkey = os_zalloc(len); if (nkey == NULL) return -1; nkey->Length = len; - nkey->KeyIndex = key_idx; - if (set_tx) + nkey->KeyIndex = params->key_idx; + if (params->set_tx) nkey->KeyIndex |= 1 << 31; if (pairwise) nkey->KeyIndex |= 1 << 30; - if (seq && seq_len) + if (params->seq && params->seq_len) nkey->KeyIndex |= 1 << 29; - nkey->KeyLength = key_len; + nkey->KeyLength = params->key_len; os_memcpy(nkey->BSSID, bssid, ETH_ALEN); - if (seq && seq_len) { - for (i = 0; i < seq_len; i++) - nkey->KeyRSC |= (ULONGLONG) seq[i] << (i * 8); - } - if (alg == WPA_ALG_TKIP && key_len == 32) { - os_memcpy(nkey->KeyMaterial, key, 16); - os_memcpy(nkey->KeyMaterial + 16, key + 24, 8); - os_memcpy(nkey->KeyMaterial + 24, key + 16, 8); + if (params->seq && params->seq_len) { + for (i = 0; i < params->seq_len; i++) + nkey->KeyRSC |= (ULONGLONG) params->seq[i] << (i * 8); + } + if (params->alg == WPA_ALG_TKIP && params->key_len == 32) { + os_memcpy(nkey->KeyMaterial, params->key, 16); + os_memcpy(nkey->KeyMaterial + 16, params->key + 24, 8); + os_memcpy(nkey->KeyMaterial + 24, params->key + 16, 8); } else { - os_memcpy(nkey->KeyMaterial, key, key_len); + os_memcpy(nkey->KeyMaterial, params->key, params->key_len); } wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY", @@ -1035,7 +1034,7 @@ 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) + struct driver_set_key_params *params) { return wpa_driver_ndis_set_key(params->ifname, priv, params->alg, params->addr, @@ -1087,7 +1086,7 @@ wpa_driver_ndis_associate(void *priv, bcast, i, i == params->wep_tx_keyidx, NULL, 0, params->wep_key[i], - params->wep_key_len[i]); + params->wep_key_len[i], 0); } } @@ -1124,7 +1123,7 @@ wpa_driver_ndis_associate(void *priv, wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP, bcast, 0, 1, NULL, 0, dummy_key, - sizeof(dummy_key)); + sizeof(dummy_key), 0); } #endif /* CONFIG_WPS */ } else { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 64bea49e1..679051f47 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3012,7 +3012,7 @@ static int nl80211_set_pmk(struct wpa_driver_nl80211_data *drv, static int wpa_driver_nl80211_set_key(struct i802_bss *bss, - struct wpa_driver_set_key_params *params) + struct driver_set_key_params *params) { struct wpa_driver_nl80211_data *drv = bss->drv; int ifindex; @@ -3478,7 +3478,7 @@ static int wpa_driver_nl80211_authenticate( enum nl80211_iftype nlmode; int count = 0; int is_retry; - struct wpa_driver_set_key_params p; + struct driver_set_key_params p; nl80211_unmask_11b_rates(bss); @@ -8730,7 +8730,7 @@ nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr) static int driver_nl80211_set_key(void *priv, - struct wpa_driver_set_key_params *params) + struct driver_set_key_params *params) { struct i802_bss *bss = priv; diff --git a/src/drivers/driver_openbsd.c b/src/drivers/driver_openbsd.c index e0eede96b..0c63721e8 100644 --- a/src/drivers/driver_openbsd.c +++ b/src/drivers/driver_openbsd.c @@ -69,7 +69,7 @@ wpa_driver_openbsd_get_capa(void *priv, struct wpa_driver_capa *capa) static int -wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params) +wpa_driver_openbsd_set_key(void *priv, struct driver_set_key_params *params) { struct openbsd_driver_data *drv = priv; struct ieee80211_keyavail keyavail; @@ -77,14 +77,14 @@ wpa_driver_openbsd_set_key(void *priv, struct wpa_driver_set_key_params *params) const u8 *key = params->key; size_t key_len = params->key_len; - if (alg != WPA_ALG_PMK || key_len > IEEE80211_PMK_LEN) + if (params->alg != WPA_ALG_PMK || params->key_len > IEEE80211_PMK_LEN) return -1; memset(&keyavail, 0, sizeof(keyavail)); os_strlcpy(keyavail.i_name, drv->ifname, sizeof(keyavail.i_name)); if (wpa_driver_openbsd_get_bssid(priv, keyavail.i_macaddr) < 0) return -1; - memcpy(keyavail.i_key, key, key_len); + memcpy(keyavail.i_key, params->key, params->key_len); if (ioctl(drv->sock, SIOCS80211KEYAVAIL, &keyavail) < 0) return -1; diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c index 807657ebc..9f2b016bf 100644 --- a/src/drivers/driver_privsep.c +++ b/src/drivers/driver_privsep.c @@ -206,37 +206,31 @@ wpa_driver_privsep_get_scan_results2(void *priv) static int wpa_driver_privsep_set_key(void *priv, - struct wpa_driver_set_key_params *params) + struct 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); + __func__, priv, params->alg, params->key_idx, set_tx); os_memset(&cmd, 0, sizeof(cmd)); - cmd.alg = alg; - if (addr) - os_memcpy(cmd.addr, addr, ETH_ALEN); + cmd.alg = params->alg; + if (params->addr) + os_memcpy(cmd.addr, params->addr, ETH_ALEN); else os_memset(cmd.addr, 0xff, ETH_ALEN); - cmd.key_idx = key_idx; - cmd.set_tx = set_tx; - if (seq && seq_len > 0 && seq_len < sizeof(cmd.seq)) { - os_memcpy(cmd.seq, seq, seq_len); - cmd.seq_len = seq_len; - } - if (key && key_len > 0 && key_len < sizeof(cmd.key)) { - os_memcpy(cmd.key, key, key_len); - cmd.key_len = key_len; + cmd.set_tx = params->set_tx; + cmd.key_flag = params->key_flag; + if (params->seq && params->seq_len > 0 && + params->seq_len < sizeof(cmd.seq)) { + os_memcpy(cmd.seq, params->seq, params->seq_len); + cmd.seq_len = params->seq_len; + } + if (params->key && params->key_len > 0 && + params->key_len < sizeof(cmd.key)) { + os_memcpy(cmd.key, params->key, params->key_len); + cmd.key_len = params->key_len; } return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_KEY, &cmd, sizeof(cmd), diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 776eff72d..4917e864a 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -1810,32 +1810,27 @@ static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg, * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. */ static int wpa_driver_wext_set_key(void *priv, - struct wpa_driver_set_key_params *params) + struct 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", - __FUNCTION__, alg, key_idx, set_tx, - (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); + __FUNCTION__, params->alg, params->key_idx, params->set_tx, + (unsigned long) params->seq_len, + (unsigned long) params->key_len); + + ret = wpa_driver_wext_set_key_ext(drv, params->alg, params->addr, + params->key_idx, params->set_tx, + params->seq, params->seq_len, + params->key, params->key_len); if (ret == 0) return 0; if (ret == -2 && - (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) { + (params->alg == WPA_ALG_NONE || params->alg == WPA_ALG_WEP)) { wpa_printf(MSG_DEBUG, "Driver did not support " "SIOCSIWENCODEEXT, trying SIOCSIWENCODE"); ret = 0; @@ -1847,12 +1842,12 @@ static int wpa_driver_wext_set_key(void *priv, os_memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = key_idx + 1; + iwr.u.encoding.flags = params->key_idx + 1; iwr.u.encoding.flags |= IW_ENCODE_TEMP; - if (alg == WPA_ALG_NONE) + if (params->alg == WPA_ALG_NONE) iwr.u.encoding.flags |= IW_ENCODE_DISABLED; - iwr.u.encoding.pointer = (caddr_t) key; - iwr.u.encoding.length = key_len; + iwr.u.encoding.pointer = (caddr_t) params->key; + iwr.u.encoding.length = params->key_len; if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]: %s", @@ -1860,10 +1855,10 @@ static int wpa_driver_wext_set_key(void *priv, ret = -1; } - if (set_tx && alg != WPA_ALG_NONE) { + if (params->set_tx && params->alg != WPA_ALG_NONE) { os_memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = key_idx + 1; + iwr.u.encoding.flags = params->key_idx + 1; iwr.u.encoding.flags |= IW_ENCODE_TEMP; iwr.u.encoding.pointer = (caddr_t) NULL; iwr.u.encoding.length = 0; diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index bb8973942..7cddc5e68 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -177,8 +177,13 @@ 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, KEY_FLAG_PAIRWISE) < 0) { + struct driver_set_key_params params; + + os_memset(¶ms, 0, sizeof(params)); + params.addr = peer->addr; + params.key_flag = KEY_FLAG_PAIRWISE; + + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from " "the driver"); return -1; @@ -190,9 +195,9 @@ static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) { + struct driver_set_key_params params; u8 key_len; u8 rsc[6]; - enum wpa_alg alg; if (peer->tk_set) { /* @@ -209,10 +214,11 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) } os_memset(rsc, 0, 6); + os_memset(¶ms, 0, sizeof(params)); switch (peer->cipher) { case WPA_CIPHER_CCMP: - alg = WPA_ALG_CCMP; + params.alg = WPA_ALG_CCMP; key_len = 16; break; case WPA_CIPHER_NONE: @@ -225,11 +231,18 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) return -1; } + params.set_tx = 1; + params.addr = peer->addr; + params.key_idx = -1; + params.seq = rsc; + params.seq_len = sizeof(rsc); + params.key = peer->tpk.tk; + params.key_len = key_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + 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, - KEY_FLAG_PAIRWISE_RX_TX) < 0) { + if (wpa_sm_set_key(sm, ¶ms) < 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 5f08d0e78..cff8daa5e 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -792,9 +792,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, const struct wpa_eapol_key *key, enum key_flag key_flag) { - int keylen, rsclen; - enum wpa_alg alg; - const u8 *key_rsc; + struct driver_set_key_params params; if (sm->ptk.installed) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, @@ -818,29 +816,34 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, return -1; } - alg = wpa_cipher_to_alg(sm->pairwise_cipher); - keylen = wpa_cipher_key_len(sm->pairwise_cipher); - if (keylen <= 0 || (unsigned int) keylen != sm->ptk.tk_len) { - wpa_printf(MSG_DEBUG, "WPA: TK length mismatch: %d != %lu", - keylen, (long unsigned int) sm->ptk.tk_len); + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.addr = sm->bssid; + params.alg = wpa_cipher_to_alg(sm->pairwise_cipher); + params.seq_len = wpa_cipher_rsc_len(sm->pairwise_cipher); + params.key_len = wpa_cipher_key_len(sm->pairwise_cipher); + params.key = sm->ptk.tk; + params.key_flag = KEY_FLAG_PAIRWISE | key_flag; + + if (params.key_len <= 0 || + (unsigned int) params.key_len != sm->ptk.tk_len) { + wpa_printf(MSG_DEBUG, "WPA: TK length mismatch: %lu != %lu", + params.key_len, (long unsigned int) sm->ptk.tk_len); return -1; } - rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher); if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) { - key_rsc = null_rsc; + params.seq = null_rsc; } else { - key_rsc = key->key_rsc; - wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen); + params.seq = key->key_rsc; + wpa_hexdump(MSG_DEBUG, "WPA: RSC", params.seq, params.seq_len); } - if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen, - sm->ptk.tk, keylen, - KEY_FLAG_PAIRWISE | key_flag) < 0) { + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set PTK to the " - "driver (alg=%d keylen=%d bssid=" MACSTR ")", - alg, keylen, MAC2STR(sm->bssid)); + "driver (alg=%d keylen=%lu bssid=" MACSTR ")", + params.alg, params.key_len, MAC2STR(sm->bssid)); return -1; } @@ -899,6 +902,7 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, const struct wpa_gtk_data *gd, const u8 *key_rsc, int wnm_sleep) { + struct driver_set_key_params params; const u8 *_gtk = gd->gtk; u8 gtk_buf[32]; @@ -926,26 +930,37 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, os_memcpy(gtk_buf + 24, gd->gtk + 16, 8); _gtk = gtk_buf; } + + os_memset(¶ms, 0, sizeof(params)); + params.alg = gd->alg; + params.key_idx = gd->keyidx; + params.seq = key_rsc; + params.seq_len = gd->key_rsc_len; + params.key = _gtk; + params.key_len = gd->gtk_len; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; + 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, - KEY_FLAG_GROUP_RX_TX_DEFAULT) < 0) { + params.set_tx = 1; + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: Failed to set GTK to the driver " "(Group only)"); forced_memzero(gtk_buf, sizeof(gtk_buf)); return -1; } - } 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, 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)", - gd->alg, gd->gtk_len, gd->keyidx); + } else { + params.set_tx = gd->tx; + params.addr = broadcast_ether_addr; + params.key_flag = KEY_FLAG_GROUP_RX; + if (wpa_sm_set_key(sm, ¶ms) < 0) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Failed to set GTK to " + "the driver (alg=%d keylen=%d keyidx=%d)", + gd->alg, gd->gtk_len, gd->keyidx); forced_memzero(gtk_buf, sizeof(gtk_buf)); return -1; + } } forced_memzero(gtk_buf, sizeof(gtk_buf)); @@ -1066,35 +1081,43 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm, const struct wpa_igtk_kde *igtk, int wnm_sleep) { - size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); - u16 keyidx = WPA_GET_LE16(igtk->keyid); + struct driver_set_key_params params; + + os_memset(¶ms, 0, sizeof(params)); + params.key_idx = WPA_GET_LE16(igtk->keyid); + params.key_len = wpa_cipher_key_len(sm->mgmt_group_cipher); /* Detect possible key reinstallation */ - if ((sm->igtk.igtk_len == len && + if ((sm->igtk.igtk_len == params.key_len && os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) || - (sm->igtk_wnm_sleep.igtk_len == len && + (sm->igtk_wnm_sleep.igtk_len == params.key_len && os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk, sm->igtk_wnm_sleep.igtk_len) == 0)) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", - keyidx); + params.key_idx); return 0; } wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d pn " COMPACT_MACSTR, - keyidx, MAC2STR(igtk->pn)); - wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); - if (keyidx > 4095) { + params.key_idx, MAC2STR(igtk->pn)); + wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, params.key_len); + if (params.key_idx > 4095) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "WPA: Invalid IGTK KeyID %d", keyidx); + "WPA: Invalid IGTK KeyID %d", params.key_idx); return -1; } - 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, KEY_FLAG_GROUP_RX) < 0) { - if (keyidx == 0x0400 || keyidx == 0x0500) { + + params.alg = wpa_cipher_to_alg(sm->mgmt_group_cipher); + params.addr = broadcast_ether_addr; + params.seq = igtk->pn; + params.seq_len = sizeof(igtk->pn); + params.key = igtk->igtk; + params.key_flag = KEY_FLAG_GROUP_RX; + + if (wpa_sm_set_key(sm, ¶ms) < 0) { + if (params.key_idx == 0x0400 || params.key_idx == 0x0500) { /* Assume the AP has broken PMF implementation since it * seems to have swapped the KeyID bytes. The AP cannot * be trusted to implement BIP correctly or provide a @@ -1118,11 +1141,11 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm, } if (wnm_sleep) { - sm->igtk_wnm_sleep.igtk_len = len; + sm->igtk_wnm_sleep.igtk_len = params.key_len; os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk, sm->igtk_wnm_sleep.igtk_len); } else { - sm->igtk.igtk_len = len; + sm->igtk.igtk_len = params.key_len; os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); } @@ -4383,11 +4406,10 @@ static void fils_process_hlp_container(struct wpa_sm *sm, const u8 *pos, int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) { + struct driver_set_key_params params; const struct ieee80211_mgmt *mgmt; const u8 *end, *ie_start; struct ieee802_11_elems elems; - int keylen, rsclen; - enum wpa_alg alg; struct wpa_gtk_data gd; int maxkeylen; struct wpa_eapol_ie_parse kde; @@ -4566,22 +4588,29 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) goto fail; } - alg = wpa_cipher_to_alg(sm->pairwise_cipher); - keylen = wpa_cipher_key_len(sm->pairwise_cipher); - if (keylen <= 0 || (unsigned int) keylen != sm->ptk.tk_len) { - wpa_printf(MSG_DEBUG, "FILS: TK length mismatch: %u != %lu", - keylen, (long unsigned int) sm->ptk.tk_len); + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.addr = sm->bssid; + params.alg = wpa_cipher_to_alg(sm->pairwise_cipher); + params.key_len = wpa_cipher_key_len(sm->pairwise_cipher); + if (params.key_len <= 0 || + (unsigned int) params.key_len != sm->ptk.tk_len) { + wpa_printf(MSG_DEBUG, "FILS: TK length mismatch: %lu != %lu", + params.key_len, (long unsigned int) sm->ptk.tk_len); goto fail; } - rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher); + params.key = sm->ptk.tk; + params.seq = null_rsc; + params.seq_len = wpa_cipher_rsc_len(sm->pairwise_cipher); + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + 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, KEY_FLAG_PAIRWISE_RX_TX) < 0) { + sm->ptk.tk, params.key_len); + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid=" + "FILS: Failed to set PTK to the driver (alg=%d keylen=%lu bssid=" MACSTR ")", - alg, keylen, MAC2STR(sm->bssid)); + params.alg, params.key_len, MAC2STR(sm->bssid)); goto fail; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 85fedeeae..a0aab1b4b 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -19,6 +19,7 @@ struct eapol_sm; struct wpa_config_blob; struct hostapd_freq_params; struct wpa_channel_info; +struct driver_set_key_params; struct wpa_sm_ctx { void *ctx; /* pointer to arbitrary upper level context */ @@ -26,11 +27,8 @@ struct wpa_sm_ctx { void (*set_state)(void *ctx, enum wpa_states state); enum wpa_states (*get_state)(void *ctx); - void (*deauthenticate)(void * ctx, u16 reason_code); - 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, enum key_flag key_flag); + void (*deauthenticate)(void *ctx, u16 reason_code); + int (*set_key)(void *ctx, struct driver_set_key_params *params); 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 8a8c545d3..f4cb118dc 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -407,9 +407,10 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid) { - int keylen; - enum wpa_alg alg; - u8 null_rsc[6] = { 0, 0, 0, 0, 0, 0 }; + struct driver_set_key_params params; + u8 null_rsc[6]; + + os_memset(&null_rsc, 0, sizeof(null_rsc)); wpa_printf(MSG_DEBUG, "FT: Installing PTK to the driver."); @@ -419,12 +420,18 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid) return -1; } - alg = wpa_cipher_to_alg(sm->pairwise_cipher); - keylen = wpa_cipher_key_len(sm->pairwise_cipher); + os_memset(¶ms, 0, sizeof(params)); + + params.set_tx = 1; + params.addr = bssid; + params.alg = wpa_cipher_to_alg(sm->pairwise_cipher); + params.seq = null_rsc; + params.seq_len = sizeof(null_rsc); + params.key = (u8 *) sm->ptk.tk; + params.key_len = wpa_cipher_key_len(sm->pairwise_cipher); + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; - 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) { + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver"); return -1; } @@ -704,13 +711,15 @@ void wpa_reset_ft_completed(struct wpa_sm *sm) static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem, size_t gtk_elem_len) { + struct driver_set_key_params params; u8 gtk[32]; - int keyidx; - enum wpa_alg alg; - size_t gtk_len, keylen, rsc_len; + size_t gtk_len; const u8 *kek; size_t kek_len; + os_memset(¶ms, 0, sizeof(params)); + + if (wpa_key_mgmt_fils(sm->key_mgmt)) { kek = sm->ptk.kek2; kek_len = sm->ptk.kek2_len; @@ -740,32 +749,33 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem, return -1; } - keylen = wpa_cipher_key_len(sm->group_cipher); - rsc_len = wpa_cipher_rsc_len(sm->group_cipher); - alg = wpa_cipher_to_alg(sm->group_cipher); - if (alg == WPA_ALG_NONE) { + params.key_len = wpa_cipher_key_len(sm->group_cipher); + params.seq_len = wpa_cipher_rsc_len(sm->group_cipher); + params.alg = wpa_cipher_to_alg(sm->group_cipher); + if (params.alg == WPA_ALG_NONE) { wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d", sm->group_cipher); return -1; } - if (gtk_len < keylen) { + if (gtk_len < params.key_len) { wpa_printf(MSG_DEBUG, "FT: Too short GTK in FTIE"); return -1; } /* Key Info[2] | Key Length[1] | RSC[8] | Key[5..32]. */ - keyidx = WPA_GET_LE16(gtk_elem) & 0x03; + params.key_idx = WPA_GET_LE16(gtk_elem) & 0x03; - if (gtk_elem[2] != keylen) { + if (gtk_elem[2] != params.key_len) { wpa_printf(MSG_DEBUG, "FT: GTK length mismatch: received %d " "negotiated %lu", - gtk_elem[2], (unsigned long) keylen); + gtk_elem[2], (unsigned long) params.key_len); return -1; } - wpa_hexdump_key(MSG_DEBUG, "FT: GTK from Reassoc Resp", gtk, keylen); + wpa_hexdump_key(MSG_DEBUG, "FT: GTK from Reassoc Resp", + gtk, params.key_len); if (sm->group_cipher == WPA_CIPHER_TKIP) { /* Swap Tx/Rx keys for Michael MIC */ u8 tmp[8]; @@ -773,9 +783,13 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem, os_memcpy(gtk + 16, gtk + 24, 8); 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, - KEY_FLAG_GROUP_RX) < 0) { + + params.addr = broadcast_ether_addr; + params.seq = gtk_elem + 3; + params.key = gtk; + params.key_flag = KEY_FLAG_GROUP_RX; + + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the " "driver."); return -1; @@ -788,9 +802,8 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem, static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem, size_t igtk_elem_len) { + struct driver_set_key_params params; u8 igtk[WPA_IGTK_MAX_LEN]; - size_t igtk_len; - u16 keyidx; const u8 *kek; size_t kek_len; @@ -816,19 +829,21 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem, wpa_hexdump_key(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp", igtk_elem, igtk_elem_len); - igtk_len = wpa_cipher_key_len(sm->mgmt_group_cipher); - if (igtk_elem_len != 2 + 6 + 1 + igtk_len + 8) { + os_memset(¶ms, 0, sizeof(params)); + params.key_len = wpa_cipher_key_len(sm->mgmt_group_cipher); + + if (igtk_elem_len != 2 + 6 + 1 + params.key_len + 8) { wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem " "length %lu", (unsigned long) igtk_elem_len); return -1; } - if (igtk_elem[8] != igtk_len) { + if (igtk_elem[8] != params.key_len) { wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem Key Length " "%d", igtk_elem[8]); return -1; } - if (aes_unwrap(kek, kek_len, igtk_len / 8, igtk_elem + 9, igtk)) { + if (aes_unwrap(kek, kek_len, params.key_len / 8, igtk_elem + 9, igtk)) { wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not " "decrypt IGTK"); return -1; @@ -836,14 +851,17 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem, /* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */ - keyidx = WPA_GET_LE16(igtk_elem); - - wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk, - 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, - KEY_FLAG_GROUP_RX) < 0) { + params.addr = broadcast_ether_addr; + params.alg = wpa_cipher_to_alg(sm->mgmt_group_cipher); + params.seq = igtk_elem + 2; + params.seq_len = 6; + params.key = igtk; + params.key_idx = WPA_GET_LE16(igtk_elem); + params.key_flag = KEY_FLAG_GROUP_RX; + + wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", + params.key, params.key_len); + if (wpa_sm_set_key(sm, ¶ms) < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the " "driver."); forced_memzero(igtk, sizeof(igtk)); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 7d7c06ef2..3991e7b63 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -195,15 +195,11 @@ static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code) sm->ctx->deauthenticate(sm->ctx->ctx, 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, - enum key_flag key_flag) +static inline int wpa_sm_set_key(struct wpa_sm *sm, + struct driver_set_key_params *params) { 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, key_flag); + return sm->ctx->set_key(sm->ctx->ctx, params); } static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 65dcb90f1..27c22110c 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5343,23 +5343,19 @@ static void wpa_supplicant_ctrl_iface_bss_flush( #ifdef CONFIG_TESTING_OPTIONS static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) { + struct driver_set_key_params params; + 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, 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, KEY_FLAG_PAIRWISE); + os_memset(¶ms, 0, sizeof(params)); + params.key_flag = KEY_FLAG_GROUP; + for (; params.key_idx <= 5; params.key_idx++) + /* MLME-DELETEKEYS.request */ + wpa_drv_set_key(wpa_s, ¶ms); + + params.addr = wpa_s->bssid; + params.key_idx = 0; + params.key_flag = KEY_FLAG_PAIRWISE; + wpa_drv_set_key(wpa_s, ¶ms); /* MLME-SETPROTECTION.request(None) */ wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, MLME_SETPROTECTION_PROTECT_TYPE_NONE, @@ -9345,6 +9341,7 @@ static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s, static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s) { + struct driver_set_key_params params; u8 zero[WPA_TK_MAX_LEN]; if (wpa_s->last_tk_alg == WPA_ALG_NONE) @@ -9352,20 +9349,24 @@ static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s) wpa_printf(MSG_INFO, "TESTING: Reset PN"); os_memset(zero, 0, sizeof(zero)); + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.alg = wpa_s->last_tk_alg; + params.addr = wpa_s->last_tk_addr; + params.key_idx = wpa_s->last_tk_key_idx; + params.seq = params.key = zero; + params.seq_len = 6; + params.key_len = wpa_s->last_tk_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; /* First, use a zero key to avoid any possible duplicate key avoidance * 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, - KEY_FLAG_PAIRWISE_RX_TX) < 0) + if (wpa_drv_set_key(wpa_s, ¶ms) < 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, - KEY_FLAG_PAIRWISE_RX_TX); + params.key = wpa_s->last_tk; + return wpa_drv_set_key(wpa_s, ¶ms); } diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 45b62bdea..f06240681 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -144,34 +144,17 @@ static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid) } 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, - enum key_flag key_flag) -{ - 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; - params.key_flag = key_flag; - - if (alg != WPA_ALG_NONE) { - if (key_idx >= 0 && key_idx <= 6) - wpa_s->keys_cleared &= ~BIT(key_idx); + struct driver_set_key_params *params) +{ + if (params->alg != WPA_ALG_NONE) { + if (params->key_idx >= 0 && params->key_idx <= 6) + wpa_s->keys_cleared &= ~BIT(params->key_idx); else wpa_s->keys_cleared = 0; } if (wpa_s->driver->set_key) { - return wpa_s->driver->set_key(wpa_s->drv_priv, ¶ms); + params->ifname = wpa_s->ifname; + return wpa_s->driver->set_key(wpa_s->drv_priv, params); } return -1; } diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 37368c4cb..9855845a7 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -143,20 +143,20 @@ 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, enum key_flag key_flag) +static int supp_set_key(void *ctx, struct driver_set_key_params *params) { struct ibss_rsn_peer *peer = ctx; wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d " "set_tx=%d)", - __func__, alg, MAC2STR(addr), key_idx, set_tx); - wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len); - wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len); - - if (key_idx == 0) { + __func__, params->alg, MAC2STR(params->addr), + params->key_idx, params->set_tx); + wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", + params->seq, params->seq_len); + wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", + params->key, params->key_len); + + if (params->key_idx == 0) { peer->authentication_status |= IBSS_RSN_SET_PTK_SUPP; ibss_check_rsn_completed(peer); /* @@ -170,10 +170,9 @@ 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, key_flag); + if (is_broadcast_ether_addr(params->addr)) + params->addr = peer->addr; + return wpa_drv_set_key(peer->ibss_rsn->wpa_s, params); } @@ -305,29 +304,39 @@ 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, - enum key_flag key_flag) +static int auth_set_key(void *ctx, struct wpa_set_key_params *wpa_params) { + struct driver_set_key_params params; struct ibss_rsn *ibss_rsn = ctx; u8 seq[6]; os_memset(seq, 0, sizeof(seq)); - - if (addr) { + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.addr = wpa_params->addr; + params.alg = wpa_params->alg; + params.key_idx = wpa_params->key_idx; + params.seq = seq; + params.seq_len = 6; + params.key = wpa_params->key; + params.key_len = wpa_params->key_len; + + if (params.addr) { wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR " key_idx=%d)", - __func__, alg, MAC2STR(addr), idx); + __func__, params.alg, MAC2STR(params.addr), + params.key_idx); } else { wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)", - __func__, alg, idx); + __func__, params.alg, params.key_idx); } - wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len); + wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", + params.key, params.key_len); - if (idx == 0) { - if (addr) { + if (params.key_idx == 0) { + if (params.addr) { struct ibss_rsn_peer *peer; - peer = ibss_rsn_get_peer(ibss_rsn, addr); + peer = ibss_rsn_get_peer(ibss_rsn, params.addr); if (peer) { peer->authentication_status |= IBSS_RSN_SET_PTK_AUTH; @@ -338,15 +347,15 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, * In IBSS RSN, the pairwise key from the 4-way handshake * initiated by the peer with highest MAC address is used. */ - if (addr == NULL || - os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) { + if (params.addr == NULL || + os_memcmp(ibss_rsn->wpa_s->own_addr, + params.addr, ETH_ALEN) < 0) { wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK"); return 0; } } - return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx, - 1, seq, 6, key, key_len, key_flag); + return wpa_drv_set_key(ibss_rsn->wpa_s, ¶ms); } @@ -847,6 +856,7 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { + struct driver_set_key_params params; wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); @@ -856,10 +866,12 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, /* Clear the TK for this pair to allow recovery from the case * where the peer STA has restarted and lost its key while we * still have a pairwise key configured. */ + os_memset(¶ms, 0, sizeof(params)); + params.addr = addr; + params.key_flag = KEY_FLAG_PAIRWISE; 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, KEY_FLAG_PAIRWISE); + wpa_drv_set_key(ibss_rsn->wpa_s, ¶ms); } if (peer && diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index 31dd1d3c6..4b075a396 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -866,42 +866,58 @@ void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt) static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s, struct sta_info *sta) { + struct driver_set_key_params params; struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; struct mesh_conf *conf = wpa_s->ifmsh->mconf; - u8 seq[6] = {}; + u8 seq[6]; + + os_memset(seq, 0, sizeof(seq)); + os_memset(¶ms, 0, sizeof(params)); + params.addr = sta->addr; wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established", MAC2STR(sta->addr)); if (conf->security & MESH_CONF_SEC_AMPE) { - 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, - KEY_FLAG_PAIRWISE_RX_TX); + params.alg = wpa_cipher_to_alg(conf->pairwise_cipher); + params.seq = seq; + params.seq_len = sizeof(seq); + params.key = sta->mtk; + params.key_len = sta->mtk_len; + params.key_flag = KEY_FLAG_PAIRWISE_RX_TX; + + wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", + params.key, params.key_len); + wpa_drv_set_key(wpa_s, ¶ms); + + params.alg = wpa_cipher_to_alg(conf->group_cipher); + params.key_idx = sta->mgtk_key_id; + params.seq = sta->mgtk_rsc; + params.seq_len = sizeof(sta->mgtk_rsc); + params.key = sta->mgtk; + params.key_len = sta->mgtk_len; + params.key_flag = KEY_FLAG_GROUP_RX; wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC", - sta->mgtk_rsc, sizeof(sta->mgtk_rsc)); + params.seq, params.seq_len); wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK", - sta->mgtk, sta->mgtk_len); - 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, - KEY_FLAG_GROUP_RX); + params.key, params.key_len); + wpa_drv_set_key(wpa_s, ¶ms); if (sta->igtk_len) { + params.alg = wpa_cipher_to_alg(conf->mgmt_group_cipher); + params.key_idx = sta->igtk_key_id; + params.seq = sta->igtk_rsc; + params.seq_len = sizeof(sta->igtk_rsc); + params.key = sta->igtk; + params.key_len = sta->igtk_len; + params.key_flag = KEY_FLAG_GROUP_RX; + wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC", - sta->igtk_rsc, sizeof(sta->igtk_rsc)); + params.seq, params.seq_len); wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK", - sta->igtk, sta->igtk_len); - wpa_drv_set_key( - 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, - KEY_FLAG_GROUP_RX); + params.key, params.key_len); + wpa_drv_set_key(wpa_s, ¶ms); } } diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c index f19bfbfc6..d712c8423 100644 --- a/wpa_supplicant/mesh_rsn.c +++ b/wpa_supplicant/mesh_rsn.c @@ -99,27 +99,36 @@ 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, - enum key_flag key_flag) +static int auth_set_key(void *ctx, struct wpa_set_key_params *wpa_params) { + struct driver_set_key_params params; struct mesh_rsn *mesh_rsn = ctx; u8 seq[6]; os_memset(seq, 0, sizeof(seq)); - - if (addr) { + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.addr = wpa_params->addr; + params.alg = wpa_params->alg; + params.key_idx = wpa_params->key_idx; + params.seq = seq; + params.seq_len = 6; + params.key = wpa_params->key; + params.key_len = wpa_params->key_len; + + if (params.addr) { wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR " key_idx=%d)", - __func__, alg, MAC2STR(addr), idx); + __func__, params.alg, MAC2STR(params.addr), + params.key_idx); } else { wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)", - __func__, alg, idx); + __func__, params.alg, params.key_idx); } - wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len); + wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", + params.key, params.key_len); - return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx, - 1, seq, 6, key, key_len, key_flag); + return wpa_drv_set_key(mesh_rsn->wpa_s, ¶ms); } @@ -145,6 +154,7 @@ static int auth_start_ampe(void *ctx, const u8 *addr) static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, enum mfp_options ieee80211w, int ocv) { + struct driver_set_key_params params; struct wpa_auth_config conf; static const struct wpa_auth_callbacks cb = { .logger = auth_logger, @@ -152,7 +162,9 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, .set_key = auth_set_key, .start_ampe = auth_start_ampe, }; - u8 seq[6] = {}; + u8 seq[6]; + + os_memset(seq, 0, sizeof(seq)); wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); @@ -185,6 +197,11 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, return -1; rsn->mgtk_key_id = 1; + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = 1; + params.seq = seq; + params.seq_len = sizeof(seq); + if (ieee80211w != NO_MGMT_FRAME_PROTECTION) { rsn->igtk_len = wpa_cipher_key_len(conf.group_mgmt_cipher); if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0) @@ -192,21 +209,27 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, rsn->igtk_key_id = 4; /* group mgmt */ + params.alg = wpa_cipher_to_alg(rsn->mgmt_group_cipher); + params.key_idx = rsn->igtk_key_id; + params.key = rsn->igtk; + params.key_len = rsn->igtk_len; + params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; + wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK", - rsn->igtk, rsn->igtk_len); - 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, - KEY_FLAG_GROUP_TX_DEFAULT); + params.key, params.key_len); + wpa_drv_set_key(rsn->wpa_s, ¶ms); } /* group privacy / data frames */ + params.alg = wpa_cipher_to_alg(rsn->group_cipher); + params.key_idx = rsn->mgtk_key_id; + params.key = rsn->mgtk; + params.key_len = rsn->mgtk_len; + params.key_flag = KEY_FLAG_GROUP_TX_DEFAULT; + wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK", 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, KEY_FLAG_GROUP_TX_DEFAULT); + wpa_drv_set_key(rsn->wpa_s, ¶ms); return 0; } diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c index f42840610..4c8388150 100644 --- a/wpa_supplicant/wpa_priv.c +++ b/wpa_supplicant/wpa_priv.c @@ -391,7 +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; + struct driver_set_key_params p; if (iface->drv_priv == NULL || iface->driver->set_key == NULL) return; @@ -413,6 +413,7 @@ static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, p.seq_len = params->seq_len; p.key = params->key_len ? params->key : NULL; p.key_len = params->key_len; + p.key_flag = params->key_flag; res = iface->driver->set_key(iface->drv_priv, &p); wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 9f3d6ef60..f17b43fe2 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -133,19 +133,27 @@ static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s); /* Configure default/group WEP keys for static WEP */ int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - int i, set = 0; + struct driver_set_key_params params; + int set = 0; - for (i = 0; i < NUM_WEP_KEYS; i++) { - if (ssid->wep_key_len[i] == 0) + os_memset(¶ms, 0, sizeof(params)); + params.alg = WPA_ALG_WEP; + + + for (; params.key_idx < NUM_WEP_KEYS; params.key_idx++) { + if (ssid->wep_key_len[params.key_idx] == 0) continue; 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], - i == ssid->wep_tx_keyidx ? - KEY_FLAG_GROUP_RX_TX_DEFAULT : - KEY_FLAG_GROUP_RX_TX); + if (params.key_idx == ssid->wep_tx_keyidx) { + params.set_tx = 1; + params.key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT; + } else { + params.key_flag = KEY_FLAG_GROUP_RX_TX; + } + params.key = ssid->wep_key[params.key_idx]; + params.key_len = ssid->wep_key_len[params.key_idx]; + wpa_drv_set_key(wpa_s, ¶ms); } return set; @@ -155,12 +163,13 @@ int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { + struct driver_set_key_params params; u8 key[32]; - size_t keylen; - enum wpa_alg alg; - u8 seq[6] = { 0 }; + u8 seq[6]; int ret; + os_memset(seq, 0, sizeof(seq)); + /* IBSS/WPA-None uses only one key (Group) for both receiving and * sending unicast and multicast packets. */ @@ -176,23 +185,25 @@ int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, return -1; } + os_memset(¶ms, 0, sizeof(params)); + switch (wpa_s->group_cipher) { case WPA_CIPHER_CCMP: os_memcpy(key, ssid->psk, 16); - keylen = 16; - alg = WPA_ALG_CCMP; + params.key_len = 16; + params.alg = WPA_ALG_CCMP; break; case WPA_CIPHER_GCMP: os_memcpy(key, ssid->psk, 16); - keylen = 16; - alg = WPA_ALG_GCMP; + params.key_len = 16; + params.alg = WPA_ALG_GCMP; break; case WPA_CIPHER_TKIP: /* WPA-None uses the same Michael MIC key for both TX and RX */ os_memcpy(key, ssid->psk, 16 + 8); os_memcpy(key + 16 + 8, ssid->psk + 16, 8); - keylen = 32; - alg = WPA_ALG_TKIP; + params.key_len = 32; + params.alg = WPA_ALG_TKIP; break; default: wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for " @@ -200,11 +211,15 @@ int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, return -1; } + params.set_tx = 1; + params.seq = seq; + params.seq_len = 6; + params.key = key; + /* 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, - KEY_FLAG_GROUP_RX_TX_DEFAULT); + ret = wpa_drv_set_key(wpa_s, ¶ms); os_memset(key, 0, sizeof(key)); return ret; } @@ -731,19 +746,24 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) */ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr) { - int i, max = 6; + struct driver_set_key_params params; + int max = 6; /* MLME-DELETEKEYS.request */ - for (i = 0; i < max; i++) { - if (wpa_s->keys_cleared & BIT(i)) + os_memset(¶ms, 0, sizeof(params)); + params.key_flag = KEY_FLAG_GROUP; + + for (; params.key_idx < max; params.key_idx++) { + if (wpa_s->keys_cleared & BIT(params.key_idx)) continue; - wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0, - NULL, 0, KEY_FLAG_GROUP); + wpa_drv_set_key(wpa_s, ¶ms); } 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, KEY_FLAG_PAIRWISE); + params.addr = addr; + params.key_idx = 0; + params.key_flag = KEY_FLAG_PAIRWISE; + wpa_drv_set_key(wpa_s, ¶ms); /* 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 9d5d35607..9dcf50b5f 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -239,7 +239,9 @@ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf, static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx, const u8 *key, size_t keylen) { + struct driver_set_key_params params; struct wpa_supplicant *wpa_s = ctx; + if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 : WPA_CIPHER_WEP104; @@ -248,11 +250,18 @@ static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx, else wpa_s->group_cipher = cipher; } - return wpa_drv_set_key(wpa_s, WPA_ALG_WEP, - unicast ? wpa_s->bssid : NULL, - keyidx, unicast, NULL, 0, key, keylen, - unicast ? KEY_FLAG_PAIRWISE_RX_TX : - KEY_FLAG_GROUP_RX_TX_DEFAULT); + + os_memset(¶ms, 0, sizeof(params)); + params.set_tx = unicast; + params.addr = unicast ? wpa_s->bssid : NULL; + params.alg = WPA_ALG_WEP; + params.key_idx = keyidx; + params.key = key; + params.key_len = keylen; + params.key_flag = unicast ? KEY_FLAG_PAIRWISE_RX_TX : + KEY_FLAG_GROUP_RX_TX_DEFAULT; + + return wpa_drv_set_key(wpa_s, ¶ms); } @@ -281,6 +290,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, enum eapol_supp_result result, void *ctx) { + struct driver_set_key_params params; struct wpa_supplicant *wpa_s = ctx; int res, pmk_len; u8 pmk[PMK_LEN]; @@ -350,10 +360,14 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way " "handshake", pmk, pmk_len); - if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk, - pmk_len, KEY_FLAG_PMK)) { + os_memset(¶ms, 0, sizeof(params)); + params.alg = WPA_ALG_PMK; + params.key = pmk; + params.key_len = pmk_len; + params.key_flag = KEY_FLAG_PMK; + + if (wpa_drv_set_key(wpa_s, ¶ms)) wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver"); - } wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_auth_timeout(wpa_s); @@ -499,36 +513,36 @@ 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, - enum key_flag key_flag) +static int wpa_supplicant_set_key(void *_wpa_s, + struct driver_set_key_params *params) { struct wpa_supplicant *wpa_s = _wpa_s; - if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) { + + if (params->alg == WPA_ALG_TKIP && + params->key_idx == 0 && params->key_len == 32) { /* Clear the MIC error counter when setting a new PTK. */ wpa_s->mic_errors_seen = 0; } #ifdef CONFIG_TESTING_GET_GTK - if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) && - alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) { - os_memcpy(wpa_s->last_gtk, key, key_len); - wpa_s->last_gtk_len = key_len; + if (params->key_idx > 0 && params->addr && + is_broadcast_ether_addr(params->addr) && + params->alg != WPA_ALG_NONE && + params->key_len <= sizeof(wpa_s->last_gtk)) { + os_memcpy(wpa_s->last_gtk, params->key, params->key_len); + wpa_s->last_gtk_len = params->key_len; } #endif /* CONFIG_TESTING_GET_GTK */ #ifdef CONFIG_TESTING_OPTIONS - if (addr && !is_broadcast_ether_addr(addr)) { - wpa_s->last_tk_alg = alg; - os_memcpy(wpa_s->last_tk_addr, addr, ETH_ALEN); - wpa_s->last_tk_key_idx = key_idx; - if (key) - os_memcpy(wpa_s->last_tk, key, key_len); - wpa_s->last_tk_len = key_len; + if (params->addr && !is_broadcast_ether_addr(params->addr)) { + wpa_s->last_tk_alg = params->alg; + os_memcpy(wpa_s->last_tk_addr, params->addr, ETH_ALEN); + wpa_s->last_tk_key_idx = params->key_idx; + if (params->key) + os_memcpy(wpa_s->last_tk, params->key, params->key_len); + wpa_s->last_tk_len = params->key_len; } #endif /* CONFIG_TESTING_OPTIONS */ - return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len, - key, key_len, key_flag); + return wpa_drv_set_key(wpa_s, params); } @@ -1167,14 +1181,20 @@ static void wpa_supplicant_set_rekey_offload(void *ctx, static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk, size_t pmk_len) { + struct driver_set_key_params params; struct wpa_supplicant *wpa_s = ctx; + 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, KEY_FLAG_PMK); - else + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) { + os_memset(¶ms, 0, sizeof(params)); + params.alg = WPA_ALG_PMK; + params.key = pmk; + params.key_len = pmk_len; + return wpa_drv_set_key(wpa_s, ¶ms); + } else { return 0; + } } -- 2.24.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap