WPS: Extend per-station PSK to support ER case as well
When wpa_psk_file is used instead of wpa_psk/wpa_passphrase, each WPS Enrollee was given a unique PSK. This did not work for the station-as-Registrar case where ER would learn the current AP settings instead of enrolling itself (i.e., when using the AP PIN instead of station PIN). That case can be covered with a similar design, so generate a per-device PSK when building M7 as an AP in wpa_psk_file configuration. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
e6c96df8b6
commit
fdb45355d4
3 changed files with 27 additions and 2 deletions
|
@ -265,6 +265,29 @@ static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
|
||||||
|
|
||||||
static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
|
static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
|
if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
|
||||||
|
wps->wps->network_key_len == 0) {
|
||||||
|
char hex[65];
|
||||||
|
u8 psk[32];
|
||||||
|
/* Generate a random per-device PSK */
|
||||||
|
if (random_get_bytes(psk, sizeof(psk)) < 0)
|
||||||
|
return -1;
|
||||||
|
wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
|
||||||
|
psk, sizeof(psk));
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
|
||||||
|
(unsigned int) wps->new_psk_len * 2);
|
||||||
|
wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
|
||||||
|
wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
|
||||||
|
wpabuf_put_be16(msg, sizeof(psk) * 2);
|
||||||
|
wpabuf_put_data(msg, hex, sizeof(psk) * 2);
|
||||||
|
if (wps->wps->registrar) {
|
||||||
|
wps_cb_new_psk(wps->wps->registrar,
|
||||||
|
wps->peer_dev.mac_addr,
|
||||||
|
wps->p2p_dev_addr, psk, sizeof(psk));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
|
wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
|
||||||
(unsigned int) wps->wps->network_key_len);
|
(unsigned int) wps->wps->network_key_len);
|
||||||
wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
|
wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
|
||||||
|
|
|
@ -212,5 +212,7 @@ int wps_registrar_pbc_overlap(struct wps_registrar *reg,
|
||||||
const u8 *addr, const u8 *uuid_e);
|
const u8 *addr, const u8 *uuid_e);
|
||||||
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
|
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
|
||||||
struct wps_nfc_pw_token *token);
|
struct wps_nfc_pw_token *token);
|
||||||
|
int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
|
||||||
|
const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len);
|
||||||
|
|
||||||
#endif /* WPS_I_H */
|
#endif /* WPS_I_H */
|
||||||
|
|
|
@ -1170,7 +1170,7 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
|
int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
|
||||||
const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
|
const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
|
||||||
{
|
{
|
||||||
if (reg->new_psk_cb == NULL)
|
if (reg->new_psk_cb == NULL)
|
||||||
|
|
Loading…
Reference in a new issue