WPS: Do not build Credential with unsupported encr combination on AP

It was possible for the Registrar code to generate a Credential with
auth type WPAPSK (i.e., WPA v1) with encr type AES if the Enrollee
claimed support for WPAPSK and not WPA2PSK while the AP was configured
in mixed mode WPAPSK+WPA2PSK regardless of how wpa_pairwise (vs.
rsn_pairwise) was set since encr type was selected from the union of
wpa_pairwise and rsn_pairwise. This could result in the Enrollee
receiving a Credential that it could then not use with the AP.

Fix this by masking the encryption types separately on AP based on the
wpa_pairwise/rsn_pairwise configuration. In the example case described
above, the Credential would get auth=WPAPSK encr=TKIP instead of
auth=WPAPSK encr=AES.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2016-01-01 11:59:20 +02:00
parent d75fcb9760
commit db671e0aee
3 changed files with 40 additions and 7 deletions

View File

@ -1,6 +1,6 @@
/* /*
* hostapd / WPS integration * hostapd / WPS integration
* Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi> * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -445,6 +445,8 @@ static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx)
os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len); os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
hapd->wps->ssid_len = cred->ssid_len; hapd->wps->ssid_len = cred->ssid_len;
hapd->wps->encr_types = cred->encr_type; hapd->wps->encr_types = cred->encr_type;
hapd->wps->encr_types_rsn = cred->encr_type;
hapd->wps->encr_types_wpa = cred->encr_type;
hapd->wps->auth_types = cred->auth_type; hapd->wps->auth_types = cred->auth_type;
hapd->wps->ap_encr_type = cred->encr_type; hapd->wps->ap_encr_type = cred->encr_type;
hapd->wps->ap_auth_type = cred->auth_type; hapd->wps->ap_auth_type = cred->auth_type;
@ -1068,10 +1070,14 @@ int hostapd_init_wps(struct hostapd_data *hapd,
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
wps->auth_types |= WPS_AUTH_WPA2; wps->auth_types |= WPS_AUTH_WPA2;
if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) {
wps->encr_types |= WPS_ENCR_AES; wps->encr_types |= WPS_ENCR_AES;
if (conf->rsn_pairwise & WPA_CIPHER_TKIP) wps->encr_types_rsn |= WPS_ENCR_AES;
}
if (conf->rsn_pairwise & WPA_CIPHER_TKIP) {
wps->encr_types |= WPS_ENCR_TKIP; wps->encr_types |= WPS_ENCR_TKIP;
wps->encr_types_rsn |= WPS_ENCR_TKIP;
}
} }
if (conf->wpa & WPA_PROTO_WPA) { if (conf->wpa & WPA_PROTO_WPA) {
@ -1080,10 +1086,14 @@ int hostapd_init_wps(struct hostapd_data *hapd,
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
wps->auth_types |= WPS_AUTH_WPA; wps->auth_types |= WPS_AUTH_WPA;
if (conf->wpa_pairwise & WPA_CIPHER_CCMP) if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {
wps->encr_types |= WPS_ENCR_AES; wps->encr_types |= WPS_ENCR_AES;
if (conf->wpa_pairwise & WPA_CIPHER_TKIP) wps->encr_types_wpa |= WPS_ENCR_AES;
}
if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {
wps->encr_types |= WPS_ENCR_TKIP; wps->encr_types |= WPS_ENCR_TKIP;
wps->encr_types_wpa |= WPS_ENCR_TKIP;
}
} }
if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
@ -1123,6 +1133,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
/* Override parameters to enable security by default */ /* Override parameters to enable security by default */
wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
wps->encr_types_rsn = WPS_ENCR_AES | WPS_ENCR_TKIP;
wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
} }
wps->ap_settings = conf->ap_settings; wps->ap_settings = conf->ap_settings;

View File

@ -1,6 +1,6 @@
/* /*
* Wi-Fi Protected Setup * Wi-Fi Protected Setup
* Copyright (c) 2007-2013, Jouni Malinen <j@w1.fi> * Copyright (c) 2007-2016, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -663,6 +663,16 @@ struct wps_context {
*/ */
u16 encr_types; u16 encr_types;
/**
* encr_types_rsn - Enabled encryption types for RSN (WPS_ENCR_*)
*/
u16 encr_types_rsn;
/**
* encr_types_wpa - Enabled encryption types for WPA (WPS_ENCR_*)
*/
u16 encr_types_wpa;
/** /**
* auth_types - Authentication types (bit field of WPS_AUTH_*) * auth_types - Authentication types (bit field of WPS_AUTH_*)
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* Wi-Fi Protected Setup - Registrar * Wi-Fi Protected Setup - Registrar
* Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi> * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -1606,6 +1606,9 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
wps->cred.ssid_len = wps->wps->ssid_len; wps->cred.ssid_len = wps->wps->ssid_len;
/* Select the best authentication and encryption type */ /* Select the best authentication and encryption type */
wpa_printf(MSG_DEBUG,
"WPS: Own auth types 0x%x - masked Enrollee auth types 0x%x",
wps->wps->auth_types, wps->auth_type);
if (wps->auth_type & WPS_AUTH_WPA2PSK) if (wps->auth_type & WPS_AUTH_WPA2PSK)
wps->auth_type = WPS_AUTH_WPA2PSK; wps->auth_type = WPS_AUTH_WPA2PSK;
else if (wps->auth_type & WPS_AUTH_WPAPSK) else if (wps->auth_type & WPS_AUTH_WPAPSK)
@ -1619,6 +1622,14 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
} }
wps->cred.auth_type = wps->auth_type; wps->cred.auth_type = wps->auth_type;
wpa_printf(MSG_DEBUG,
"WPS: Own encr types 0x%x (rsn: 0x%x, wpa: 0x%x) - masked Enrollee encr types 0x%x",
wps->wps->encr_types, wps->wps->encr_types_rsn,
wps->wps->encr_types_wpa, wps->encr_type);
if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPA2PSK)
wps->encr_type &= wps->wps->encr_types_rsn;
else if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPAPSK)
wps->encr_type &= wps->wps->encr_types_wpa;
if (wps->auth_type == WPS_AUTH_WPA2PSK || if (wps->auth_type == WPS_AUTH_WPA2PSK ||
wps->auth_type == WPS_AUTH_WPAPSK) { wps->auth_type == WPS_AUTH_WPAPSK) {
if (wps->encr_type & WPS_ENCR_AES) if (wps->encr_type & WPS_ENCR_AES)