WPS: Add option for forcing Registrar to use PSK format in Credential

The use_psk_key parameter can now be used to force the Registrar to
use PSK format instead of ASCII passphrase when building a Credential
for the Enrollee. For now, this is not enabled, but it could be enabled
either based on external (to WPS) configuration or automatically set
based on some WPS attribute values from the Enrollee.
This commit is contained in:
Jouni Malinen 2009-12-21 12:46:19 +02:00 committed by Jouni Malinen
parent 0ae687bd10
commit f3f2eeba01
6 changed files with 49 additions and 1 deletions

View file

@ -619,6 +619,11 @@ int hostapd_init_wps(struct hostapd_data *hapd,
wps->network_key_len = conf->ssid.wep.len[0]; wps->network_key_len = conf->ssid.wep.len[0];
} }
if (conf->ssid.wpa_psk) {
os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN);
wps->psk_set = 1;
}
if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) {
/* 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;

View file

@ -127,6 +127,8 @@ static void * eap_wsc_init(struct eap_sm *sm)
} }
cfg.assoc_wps_ie = sm->assoc_wps_ie; cfg.assoc_wps_ie = sm->assoc_wps_ie;
cfg.peer_addr = sm->peer_addr; cfg.peer_addr = sm->peer_addr;
if (0 /* TODO: could provide option for forcing PSK format */)
cfg.use_psk_key = 1;
data->wps = wps_init(&cfg); data->wps = wps_init(&cfg);
if (data->wps == NULL) { if (data->wps == NULL) {
os_free(data); os_free(data);

View file

@ -104,6 +104,8 @@ struct wps_data * wps_init(const struct wps_config *cfg)
if (cfg->peer_addr) if (cfg->peer_addr)
os_memcpy(data->peer_dev.mac_addr, cfg->peer_addr, ETH_ALEN); os_memcpy(data->peer_dev.mac_addr, cfg->peer_addr, ETH_ALEN);
data->use_psk_key = cfg->use_psk_key;
return data; return data;
} }

View file

@ -147,6 +147,15 @@ struct wps_config {
* peer_addr: MAC address of the peer in AP; %NULL if not AP * peer_addr: MAC address of the peer in AP; %NULL if not AP
*/ */
const u8 *peer_addr; const u8 *peer_addr;
/**
* use_psk_key - Use PSK format key in Credential
*
* Force PSK format to be used instead of ASCII passphrase when
* building Credential for an Enrollee. The PSK value is set in
* struct wpa_context::psk.
*/
int use_psk_key;
}; };
struct wps_data * wps_init(const struct wps_config *cfg); struct wps_data * wps_init(const struct wps_config *cfg);
@ -554,6 +563,14 @@ struct wps_context {
* If %NULL, Registrar will generate per-device PSK. In addition, AP * If %NULL, Registrar will generate per-device PSK. In addition, AP
* uses this when acting as an Enrollee to notify Registrar of the * uses this when acting as an Enrollee to notify Registrar of the
* current configuration. * current configuration.
*
* When using WPA/WPA2-Person, this key can be either the ASCII
* passphrase (8..63 characters) or the 32-octet PSK (64 hex
* characters). When this is set to the ASCII passphrase, the PSK can
* be provided in the psk buffer and used per-Enrollee to control which
* key type is included in the Credential (e.g., to reduce calculation
* need on low-powered devices by provisioning PSK while still allowing
* other devices to get the passphrase).
*/ */
u8 *network_key; u8 *network_key;
@ -562,6 +579,19 @@ struct wps_context {
*/ */
size_t network_key_len; size_t network_key_len;
/**
* psk - The current network PSK
*
* This optional value can be used to provide the current PSK if
* network_key is set to the ASCII passphrase.
*/
u8 psk[32];
/**
* psk_set - Whether psk value is set
*/
int psk_set;
/** /**
* ap_settings - AP Settings override for M7 (only used at AP) * ap_settings - AP Settings override for M7 (only used at AP)
* *

View file

@ -113,6 +113,8 @@ struct wps_data {
void *ap_settings_cb_ctx; void *ap_settings_cb_ctx;
struct wps_credential *use_cred; struct wps_credential *use_cred;
int use_psk_key;
}; };

View file

@ -1120,7 +1120,8 @@ static int wps_build_cred_encr_type(struct wpabuf *msg,
static int wps_build_cred_network_key(struct wpabuf *msg, static int wps_build_cred_network_key(struct wpabuf *msg,
const struct wps_credential *cred) const struct wps_credential *cred)
{ {
wpa_printf(MSG_DEBUG, "WPS: * Network Key"); wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%d)",
(int) cred->key_len);
wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
wpabuf_put_be16(msg, cred->key_len); wpabuf_put_be16(msg, cred->key_len);
wpabuf_put_data(msg, cred->key, cred->key_len); wpabuf_put_data(msg, cred->key, cred->key_len);
@ -1233,6 +1234,12 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
wps->new_psk, wps->new_psk_len); wps->new_psk, wps->new_psk_len);
os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len); os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
wps->cred.key_len = wps->new_psk_len; wps->cred.key_len = wps->new_psk_len;
} else if (wps->use_psk_key && wps->wps->psk_set) {
char hex[65];
wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
os_memcpy(wps->cred.key, hex, 32 * 2);
wps->cred.key_len = 32 * 2;
} else if (wps->wps->network_key) { } else if (wps->wps->network_key) {
os_memcpy(wps->cred.key, wps->wps->network_key, os_memcpy(wps->cred.key, wps->wps->network_key,
wps->wps->network_key_len); wps->wps->network_key_len);