From 01a025937c67f0eca6021d94b8ec3b144f8b1730 Mon Sep 17 00:00:00 2001 From: Hamad Kadmany Date: Mon, 27 Apr 2015 20:42:08 +0300 Subject: [PATCH] WPS: Add support for 60 GHz band Handling of WPS RF band for 60 GHz was missing. Add it in all relevant places and also map "AES" as the cipher to GCMP instead of CCMP when operating on the 60 GHz band. Signed-off-by: Hamad Kadmany --- hostapd/config_file.c | 4 +++- hostapd/hostapd.conf | 2 +- src/ap/ap_config.c | 4 ++-- src/ap/wps_hostapd.c | 22 +++++++++++++++++----- src/wps/wps.h | 2 +- src/wps/wps_common.c | 2 ++ src/wps/wps_defs.h | 1 + src/wps/wps_registrar.c | 9 +++++++-- src/wps/wps_validate.c | 2 ++ wpa_supplicant/wps_supplicant.c | 9 ++++++++- 10 files changed, 44 insertions(+), 13 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 4976966e2..0c1f401b2 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2545,7 +2545,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, return 1; } } else if (os_strcmp(buf, "wps_rf_bands") == 0) { - if (os_strcmp(pos, "a") == 0) + if (os_strcmp(pos, "ad") == 0) + bss->wps_rf_bands = WPS_RF_60GHZ; + else if (os_strcmp(pos, "a") == 0) bss->wps_rf_bands = WPS_RF_50GHZ; else if (os_strcmp(pos, "g") == 0 || os_strcmp(pos, "b") == 0) diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index b4754b360..5c6b28d01 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1433,7 +1433,7 @@ own_ip_addr=127.0.0.1 # 12-digit, all-numeric code that identifies the consumer package. #upc=123456789012 -# WPS RF Bands (a = 5G, b = 2.4G, g = 2.4G, ag = dual band) +# WPS RF Bands (a = 5G, b = 2.4G, g = 2.4G, ag = dual band, ad = 60 GHz) # This value should be set according to RF band(s) supported by the AP if # hw_mode is not set. For dual band dual concurrent devices, this needs to be # set to ag to allow both RF bands to be advertized. diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index cccbfabb7..c44f70d6c 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -819,9 +819,9 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss, if (full_config && bss->wps_state && bss->wpa && (!(bss->wpa & 2) || - !(bss->rsn_pairwise & WPA_CIPHER_CCMP))) { + !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)))) { wpa_printf(MSG_INFO, "WPS: WPA/TKIP configuration without " - "WPA2/CCMP forced WPS to be disabled"); + "WPA2/CCMP/GCMP forced WPS to be disabled"); bss->wps_state = 0; } #endif /* CONFIG_WPS */ diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index 68eaeca1c..caed01e82 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -347,8 +347,12 @@ static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd, bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK; bss->wpa_pairwise = 0; - if (cred->encr_type & WPS_ENCR_AES) - bss->wpa_pairwise |= WPA_CIPHER_CCMP; + if (cred->encr_type & WPS_ENCR_AES) { + if (hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD) + bss->wpa_pairwise |= WPA_CIPHER_GCMP; + else + bss->wpa_pairwise |= WPA_CIPHER_CCMP; + } if (cred->encr_type & WPS_ENCR_TKIP) bss->wpa_pairwise |= WPA_CIPHER_TKIP; bss->rsn_pairwise = bss->wpa_pairwise; @@ -530,7 +534,11 @@ static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx) fprintf(nconf, "wpa_pairwise="); prefix = ""; if (cred->encr_type & WPS_ENCR_AES) { - fprintf(nconf, "CCMP"); + if (hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD) + fprintf(nconf, "GCMP"); + else + fprintf(nconf, "CCMP"); + prefix = " "; } if (cred->encr_type & WPS_ENCR_TKIP) { @@ -844,7 +852,9 @@ static int hostapd_wps_rf_band_cb(void *ctx) struct hostapd_data *hapd = ctx; return hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? - WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ + WPS_RF_50GHZ : + hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD ? + WPS_RF_60GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ } @@ -1041,7 +1051,9 @@ int hostapd_init_wps(struct hostapd_data *hapd, } else { wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? - WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ + WPS_RF_50GHZ : + hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD ? + WPS_RF_60GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ } if (conf->wpa & WPA_PROTO_RSN) { diff --git a/src/wps/wps.h b/src/wps/wps.h index c88aaa45e..2c91d1678 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -79,7 +79,7 @@ struct wps_credential { * @sec_dev_type: Array of secondary device types * @num_sec_dev_type: Number of secondary device types * @os_version: OS Version - * @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ flags) + * @rf_bands: RF bands (WPS_RF_24GHZ, WPS_RF_50GHZ, WPS_RF_60GHZ flags) * @p2p: Whether the device is a P2P device */ struct wps_device_data { diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index c1ede6a9e..16d466e0a 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -764,6 +764,8 @@ static int wps_build_ap_freq(struct wpabuf *msg, int freq) rf_band = WPS_RF_24GHZ; else if (mode == HOSTAPD_MODE_IEEE80211A) rf_band = WPS_RF_50GHZ; + else if (mode == HOSTAPD_MODE_IEEE80211AD) + rf_band = WPS_RF_60GHZ; else return 0; /* Unknown band */ ap_channel = channel; diff --git a/src/wps/wps_defs.h b/src/wps/wps_defs.h index 433415596..a23b979d2 100644 --- a/src/wps/wps_defs.h +++ b/src/wps/wps_defs.h @@ -237,6 +237,7 @@ enum wps_error_indication { /* RF Bands */ #define WPS_RF_24GHZ 0x01 #define WPS_RF_50GHZ 0x02 +#define WPS_RF_60GHZ 0x04 /* Config Methods */ #define WPS_CONFIG_USBA 0x0001 diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 48b7e1288..8bcf2b34f 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -3226,8 +3226,13 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps, os_memset(&cred, 0, sizeof(cred)); os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len); cred.ssid_len = wps->wps->ssid_len; - cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK; - cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES; + if (wps->wps->rf_band_cb(wps->wps->cb_ctx) == WPS_RF_60GHZ) { + cred.auth_type = WPS_AUTH_WPA2PSK; + cred.encr_type = WPS_ENCR_AES; + } else { + cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK; + cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES; + } os_memcpy(cred.key, wps->new_psk, wps->new_psk_len); cred.key_len = wps->new_psk_len; diff --git a/src/wps/wps_validate.c b/src/wps/wps_validate.c index 1c6a14bce..267b565e4 100644 --- a/src/wps/wps_validate.c +++ b/src/wps/wps_validate.c @@ -224,6 +224,8 @@ static int wps_validate_rf_bands(const u8 *rf_bands, int mandatory) return 0; } if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ && + *rf_bands != WPS_RF_60GHZ && + *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ | WPS_RF_60GHZ) && *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) { wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands " "attribute value 0x%x", *rf_bands); diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index e34573b66..8a5cb8e8f 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -888,7 +888,8 @@ static int wpa_supplicant_wps_rf_band(void *ctx) if (!wpa_s->current_ssid || !wpa_s->assoc_freq) return 0; - return (wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ; + return (wpa_s->assoc_freq > 50000) ? WPS_RF_60GHZ : + (wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ; } @@ -1496,6 +1497,8 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) wps->dev.rf_bands |= WPS_RF_24GHZ; else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A) wps->dev.rf_bands |= WPS_RF_50GHZ; + else if (modes[m].mode == HOSTAPD_MODE_IEEE80211AD) + wps->dev.rf_bands |= WPS_RF_60GHZ; } } if (wps->dev.rf_bands == 0) { @@ -2597,6 +2600,10 @@ static int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, (attr.rf_bands == NULL || *attr.rf_bands & WPS_RF_50GHZ)) freq = 5000 + 5 * chan; + else if (chan >= 1 && chan <= 4 && + (attr.rf_bands == NULL || + *attr.rf_bands & WPS_RF_60GHZ)) + freq = 56160 + 2160 * chan; if (freq) { wpa_printf(MSG_DEBUG,