aboutsummaryrefslogtreecommitdiffstats
path: root/src/wps
diff options
context:
space:
mode:
authorDavina Lu <ylu@quantenna.com>2019-02-12 14:35:26 (GMT)
committerJouni Malinen <j@w1.fi>2019-02-18 20:35:41 (GMT)
commit66819b07b5fc95d0ffe6defafdb9526427c1955b (patch)
treeb3e89110a031276033e98adb9e0e91838467362a /src/wps
parent83ebf558654615e02beb3be7011e63307bf328b7 (diff)
downloadhostap-66819b07b5fc95d0ffe6defafdb9526427c1955b.zip
hostap-66819b07b5fc95d0ffe6defafdb9526427c1955b.tar.gz
hostap-66819b07b5fc95d0ffe6defafdb9526427c1955b.tar.bz2
hostapd: Support Multi-AP backhaul STA onboarding with WPS
The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a backhaul STA through WPS. To enable this, the WPS Registrar offers a different set of credentials (backhaul credentials instead of fronthaul credentials) when the Multi-AP subelement is present in the WFA vendor extension element of the WSC M1 message. Add new configuration options to specify the backhaul credentials for the hostapd internal registrar: multi_ap_backhaul_ssid, multi_ap_backhaul_wpa_psk, multi_ap_backhaul_wpa_passphrase. These are only relevant for a fronthaul SSID, i.e., where multi_ap is set to 2 or 3. When these options are set, pass the backhaul credentials instead of the normal credentials when the Multi-AP subelement is present. Ignore the Multi-AP subelement if the backhaul config options are not set. Note that for an SSID which is fronthaul and backhaul at the same time (i.e., multi_ap == 3), this results in the correct credentials being sent anyway. The security to be used for the backaul BSS is fixed to WPA2PSK. The Multi-AP Specification only allows Open and WPA2PSK networks to be configured. Although not stated explicitly, the backhaul link is intended to be always encrypted, hence WPA2PSK. To build the credentials, the credential-building code is essentially copied and simplified. Indeed, the backhaul credentials are always WPA2PSK and never use per-device PSK. All the options set for the fronthaul BSS WPS are simply ignored. Signed-off-by: Davina Lu <ylu@quantenna.com> Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be> Cc: Marianna Carrera <marianna.carrera.so@quantenna.com>
Diffstat (limited to 'src/wps')
-rw-r--r--src/wps/wps.h32
-rw-r--r--src/wps/wps_attr_parse.c11
-rw-r--r--src/wps/wps_attr_parse.h1
-rw-r--r--src/wps/wps_dev_attr.c8
-rw-r--r--src/wps/wps_dev_attr.h1
-rw-r--r--src/wps/wps_registrar.c70
6 files changed, 123 insertions, 0 deletions
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 8752647..14ce863 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -100,6 +100,7 @@ struct wps_device_data {
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
int p2p;
+ u8 multi_ap_ext;
};
/**
@@ -401,6 +402,37 @@ struct wps_registrar_config {
* PSK is set for a network.
*/
int force_per_enrollee_psk;
+
+ /**
+ * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
+ * enrollee
+ *
+ * This SSID is used by the Registrar to fill in information for
+ * Credentials when the enrollee advertises it is a Multi-AP backhaul
+ * STA.
+ */
+ const u8 *multi_ap_backhaul_ssid;
+
+ /**
+ * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
+ * octets
+ */
+ size_t multi_ap_backhaul_ssid_len;
+
+ /**
+ * multi_ap_backhaul_network_key - The Network Key (PSK) for the
+ * Multi-AP backhaul enrollee.
+ *
+ * This key can be either the ASCII passphrase (8..63 characters) or the
+ * 32-octet PSK (64 hex characters).
+ */
+ const u8 *multi_ap_backhaul_network_key;
+
+ /**
+ * multi_ap_backhaul_network_key_len - Length of
+ * multi_ap_backhaul_network_key in octets
+ */
+ size_t multi_ap_backhaul_network_key_len;
};
diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c
index 756d57e..fd51635 100644
--- a/src/wps/wps_attr_parse.c
+++ b/src/wps/wps_attr_parse.c
@@ -67,6 +67,17 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
}
attr->registrar_configuration_methods = pos;
break;
+ case WFA_ELEM_MULTI_AP:
+ if (len != 1) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: Invalid Multi-AP Extension length %u",
+ len);
+ return -1;
+ }
+ attr->multi_ap_ext = *pos;
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
+ attr->multi_ap_ext);
+ break;
default:
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
"Extension subelement %u", id);
diff --git a/src/wps/wps_attr_parse.h b/src/wps/wps_attr_parse.h
index 8188fe9..4de27b2 100644
--- a/src/wps/wps_attr_parse.h
+++ b/src/wps/wps_attr_parse.h
@@ -97,6 +97,7 @@ struct wps_parse_attr {
const u8 *cred[MAX_CRED_COUNT];
const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
+ u8 multi_ap_ext;
};
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
diff --git a/src/wps/wps_dev_attr.c b/src/wps/wps_dev_attr.c
index 0d01211..b209fea 100644
--- a/src/wps/wps_dev_attr.c
+++ b/src/wps/wps_dev_attr.c
@@ -390,6 +390,14 @@ int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
}
+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
+{
+ dev->multi_ap_ext = ext;
+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x",
+ dev->multi_ap_ext);
+}
+
+
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
{
if (bands == NULL) {
diff --git a/src/wps/wps_dev_attr.h b/src/wps/wps_dev_attr.h
index c9034ad..a4b4173 100644
--- a/src/wps/wps_dev_attr.h
+++ b/src/wps/wps_dev_attr.h
@@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg);
int wps_process_device_attrs(struct wps_device_data *dev,
struct wps_parse_attr *attr);
int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
void wps_device_data_free(struct wps_device_data *dev);
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index b5ac29b..2669650 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -188,6 +188,37 @@ struct wps_registrar {
#ifdef WPS_WORKAROUNDS
struct os_reltime pbc_ignore_start;
#endif /* WPS_WORKAROUNDS */
+
+ /**
+ * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
+ * enrollee
+ *
+ * This SSID is used by the Registrar to fill in information for
+ * Credentials when the enrollee advertises it is a Multi-AP backhaul
+ * STA.
+ */
+ u8 multi_ap_backhaul_ssid[SSID_MAX_LEN];
+
+ /**
+ * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
+ * octets
+ */
+ size_t multi_ap_backhaul_ssid_len;
+
+ /**
+ * multi_ap_backhaul_network_key - The Network Key (PSK) for the
+ * Multi-AP backhaul enrollee.
+ *
+ * This key can be either the ASCII passphrase (8..63 characters) or the
+ * 32-octet PSK (64 hex characters).
+ */
+ u8 *multi_ap_backhaul_network_key;
+
+ /**
+ * multi_ap_backhaul_network_key_len - Length of
+ * multi_ap_backhaul_network_key in octets
+ */
+ size_t multi_ap_backhaul_network_key_len;
};
@@ -667,6 +698,18 @@ wps_registrar_init(struct wps_context *wps,
reg->dualband = cfg->dualband;
reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk;
+ os_memcpy(reg->multi_ap_backhaul_ssid, cfg->multi_ap_backhaul_ssid,
+ cfg->multi_ap_backhaul_ssid_len);
+ reg->multi_ap_backhaul_ssid_len = cfg->multi_ap_backhaul_ssid_len;
+ if (cfg->multi_ap_backhaul_network_key) {
+ reg->multi_ap_backhaul_network_key =
+ os_memdup(cfg->multi_ap_backhaul_network_key,
+ cfg->multi_ap_backhaul_network_key_len);
+ if (reg->multi_ap_backhaul_network_key)
+ reg->multi_ap_backhaul_network_key_len =
+ cfg->multi_ap_backhaul_network_key_len;
+ }
+
if (wps_set_ie(reg)) {
wps_registrar_deinit(reg);
return NULL;
@@ -704,6 +747,8 @@ void wps_registrar_deinit(struct wps_registrar *reg)
eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
wps_registrar_flush(reg);
wpabuf_clear_free(reg->extra_cred);
+ bin_clear_free(reg->multi_ap_backhaul_network_key,
+ reg->multi_ap_backhaul_network_key_len);
os_free(reg);
}
@@ -1592,6 +1637,7 @@ int wps_build_credential_wrap(struct wpabuf *msg,
int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
{
struct wpabuf *cred;
+ struct wps_registrar *reg = wps->wps->registrar;
if (wps->wps->registrar->skip_cred_build)
goto skip_cred_build;
@@ -1603,6 +1649,29 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
}
os_memset(&wps->cred, 0, sizeof(wps->cred));
+ if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA &&
+ reg->multi_ap_backhaul_ssid_len) {
+ wpa_printf(MSG_DEBUG, "WPS: Use backhaul STA credentials");
+ os_memcpy(wps->cred.ssid, reg->multi_ap_backhaul_ssid,
+ reg->multi_ap_backhaul_ssid_len);
+ wps->cred.ssid_len = reg->multi_ap_backhaul_ssid_len;
+ /* Backhaul is always WPA2PSK */
+ wps->cred.auth_type = WPS_AUTH_WPA2PSK;
+ wps->cred.encr_type = WPS_ENCR_AES;
+ /* Set MAC address in the Credential to be the Enrollee's MAC
+ * address
+ */
+ os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
+ if (reg->multi_ap_backhaul_network_key) {
+ os_memcpy(wps->cred.key,
+ reg->multi_ap_backhaul_network_key,
+ reg->multi_ap_backhaul_network_key_len);
+ wps->cred.key_len =
+ reg->multi_ap_backhaul_network_key_len;
+ }
+ goto use_provided;
+ }
+
os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
wps->cred.ssid_len = wps->wps->ssid_len;
@@ -2705,6 +2774,7 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
wps->use_psk_key = 1;
}
#endif /* WPS_WORKAROUNDS */
+ wps_process_vendor_ext_m1(&wps->peer_dev, attr->multi_ap_ext);
wps->state = SEND_M2;
return WPS_CONTINUE;