From: lihz <lihz@xxxxxxxxxxx> This patch adds function to download pmk/pmk_r0/pmk_r0_name for roaming offload and Marvell OUI vendor event handler. Signed-off-by: Huazeng Li <lihz@xxxxxxxxxxx> Signed-off-by: Amitkumar Karwar <akarwar@xxxxxxxxxxx> --- src/common/mrvl-vendor.h | 28 ++++++++++++++++++ src/drivers/driver_nl80211.c | 54 ++++++++++++++++++++++++++++++++++ src/drivers/driver_nl80211_event.c | 60 ++++++++++++++++++++++++++++++++++++++ src/drivers/drivers.mak | 3 ++ src/drivers/drivers.mk | 3 ++ src/rsn_supp/wpa_ft.c | 16 ++++++++++ wpa_supplicant/defconfig | 3 ++ 7 files changed, 167 insertions(+) create mode 100644 src/common/mrvl-vendor.h diff --git a/src/common/mrvl-vendor.h b/src/common/mrvl-vendor.h new file mode 100644 index 0000000..df5426f --- /dev/null +++ b/src/common/mrvl-vendor.h @@ -0,0 +1,28 @@ +/* + * Marvell OUI and vendor specific assignments + */ +#ifndef MRVL_VENDOR_H +#define MRVL_VENDOR_H + +#define OUI_MRVL 0x005043 +#define MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY 0x2 + +#define MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_OFFLOAD 0x10001 +#define MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH 0x10002 + +enum mrvl_wlan_vendor_attr_roam_auth { + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS, + /* keep last */ + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST, + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX = + MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1 +}; +#endif /* MRVL_VENDOR_H */ diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index b2b27a7..f9de8de 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -27,6 +27,7 @@ #include "eloop.h" #include "common/qca-vendor.h" #include "common/qca-vendor-attr.h" +#include "common/mrvl-vendor.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "l2_packet/l2_packet.h" @@ -2641,6 +2642,35 @@ static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv, } #endif /* CONFIG_DRIVER_NL80211_QCA */ +#ifdef CONFIG_DRIVER_NL80211_MRVL +static int issue_key_mgmt_set_pmk_mrvl(struct wpa_driver_nl80211_data *drv, + const u8 *key, size_t key_len) +{ + struct nl_msg *msg; + int ret; + + if (!(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) + return 0; + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MRVL) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY) || + nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) { + nl80211_nlmsg_clear(msg); + nlmsg_free(msg); + return -1; + } + ret = send_and_recv_msgs(drv, msg, NULL, (void *)-1); + if (ret) { + wpa_printf(MSG_DEBUG, + "nl80211: Key management set key failed: ret=%d (%s)", + ret, strerror(-ret)); + } + + return ret; +} +#endif /* CONFIG_DRIVER_NL80211_MRVL */ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, enum wpa_alg alg, const u8 *addr, @@ -2680,6 +2710,18 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, } #endif /* CONFIG_DRIVER_NL80211_QCA */ +#ifdef CONFIG_IEEE80211R +#ifdef CONFIG_DRIVER_NL80211_MRVL + if (alg == WPA_ALG_PMK && + (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) { + wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key", + __func__); + ret = issue_key_mgmt_set_pmk_mrvl(drv, key, key_len); + return ret; + } +#endif /* CONFIG_DRIVER_NL80211_MRVL */ +#endif /* CONFIG_IEEE80211R */ + if (alg == WPA_ALG_NONE) { msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY); if (!msg) @@ -4938,6 +4980,18 @@ static int wpa_driver_nl80211_try_connect( } #endif /* CONFIG_DRIVER_NL80211_QCA */ +#ifdef CONFIG_DRIVER_NL80211_MRVL + if (params->req_key_mgmt_offload && params->psk && + (params->key_mgmt_suite == WPA_KEY_MGMT_PSK || + params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 || + params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) { + wpa_printf(MSG_DEBUG, "nl80211: Key management set PMK"); + ret = issue_key_mgmt_set_pmk_mrvl(drv, params->psk, 32); + if (ret) + return ret; + } +#endif /* CONFIG_DRIVER_NL80211_MRVL */ + wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT); if (!msg) diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 762e3ac..3d3ab6b 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -15,6 +15,7 @@ #include "utils/eloop.h" #include "common/qca-vendor.h" #include "common/qca-vendor-attr.h" +#include "common/mrvl-vendor.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "driver_nl80211.h" @@ -1946,6 +1947,62 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv, } } +static void mrvl_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv, + const u8 *data, size_t len) +{ + struct nlattr *tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1]; + u8 *bssid; + + wpa_printf(MSG_DEBUG, + "nl80211: Key management roam+auth vendor event received"); + + if (nla_parse(tb, MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX, + (struct nlattr *)data, len, NULL) || + !tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] || + nla_len(tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN || + !tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] || + !tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED]) + return; + + bssid = nla_data(tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]); + wpa_printf(MSG_DEBUG, " * roam BSSID " MACSTR, MAC2STR(bssid)); + + mlme_event_connect(drv, NL80211_CMD_ROAM, NULL, + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE], + NULL, + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK], + tb[MRVL_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS]); +} + +static void nl80211_vendor_event_mrvl(struct wpa_driver_nl80211_data *drv, + u32 subcmd, u8 *data, size_t len) +{ + switch (subcmd) { +#ifdef CONFIG_DRIVER_NL80211_MRVL + case MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_OFFLOAD: + wpa_printf(MSG_DEBUG, + "nl80211: Received MRVL vendor event %u", subcmd); + if (*data) + drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD; + else + drv->capa.flags &= ~WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD; + break; + case MRVL_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: + mrvl_nl80211_key_mgmt_auth(drv, data, len); + break; +#endif + default: + wpa_printf(MSG_DEBUG, + "nl80211: Ignore unsupported MRVL vendor event %u", + subcmd); + break; + } +} static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv, struct nlattr **tb) @@ -1985,6 +2042,9 @@ static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv, case OUI_QCA: nl80211_vendor_event_qca(drv, subcmd, data, len); break; + case OUI_MRVL: + nl80211_vendor_event_mrvl(drv, subcmd, data, len); + break; default: wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event"); break; diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak index c6d3f81..4a4f3e2 100644 --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak @@ -32,6 +32,9 @@ DRV_OBJS += ../src/drivers/driver_nl80211_scan.o ifdef CONFIG_DRIVER_NL80211_QCA DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA endif +ifdef CONFIG_DRIVER_NL80211_MRVL +DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_MRVL +endif NEED_SME=y NEED_AP_MLME=y NEED_NETLINK=y diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk index c6fe4c2..d84dee7 100644 --- a/src/drivers/drivers.mk +++ b/src/drivers/drivers.mk @@ -28,6 +28,9 @@ DRV_OBJS += src/drivers/driver_nl80211_scan.c ifdef CONFIG_DRIVER_NL80211_QCA DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA endif +ifdef CONFIG_DRIVER_NL80211_MRVL +DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_MRVL +endif NEED_SME=y NEED_AP_MLME=y NEED_NETLINK=y diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 205793e..5a6fb1d 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -23,6 +23,9 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, { u8 ptk_name[WPA_PMK_NAME_LEN]; const u8 *anonce = key->key_nonce; +#ifdef CONFIG_DRIVER_NL80211_MRVL + u8 pmkr0_pmkr0name[48] = { 0 }; +#endif /* CONFIG_DRIVER_NL80211_MRVL */ if (sm->xxkey_len == 0) { wpa_printf(MSG_DEBUG, "FT: XXKey not available for key " @@ -37,6 +40,19 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", sm->pmk_r0, PMK_LEN); wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", sm->pmk_r0_name, WPA_PMK_NAME_LEN); +#ifdef CONFIG_DRIVER_NL80211_MRVL + os_memcpy(pmkr0_pmkr0name, (u8 *)sm->pmk_r0, PMK_LEN); + os_memcpy(pmkr0_pmkr0name + PMK_LEN, (u8 *)sm->pmk_r0_name, + WPA_PMK_NAME_LEN); + if (wpa_sm_set_key(sm, WPA_ALG_PMK, NULL, 0, 1, NULL, + 0, pmkr0_pmkr0name, + (PMK_LEN + WPA_PMK_NAME_LEN)) < 0) { + wpa_printf(MSG_WARNING, "FT: Failed to set + PMKR0/PMKR0NAME to the driver"); + return -1; + } +#endif /* CONFIG_DRIVER_NL80211_MRVL */ + wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_name, sm->r1kh_id, sm->own_addr, sm->pmk_r1, sm->pmk_r1_name); wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, PMK_LEN); diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index 1d05198..e2179e5 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -34,6 +34,9 @@ CONFIG_DRIVER_NL80211=y # QCA vendor extensions to nl80211 #CONFIG_DRIVER_NL80211_QCA=y +# MRVL vendor extensions to nl80211 +#CONFIG_DRIVER_NL80211_MRVL=y + # driver_nl80211.c requires libnl. If you are compiling it yourself # you may need to point hostapd to your version of libnl. # -- 1.9.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap