wpa_supplicant: wps code updation

Update WPS code with upstream. Also moved ESP specific code
in another esp code folder.
This commit is contained in:
Kapil Gupta
2021-12-17 14:20:51 +05:30
committed by BOT
parent 30fed9c891
commit ecc87cfc8d
38 changed files with 2855 additions and 2076 deletions

View File

@@ -22,6 +22,7 @@ set(srcs "port/os_xtensa.c"
"src/crypto/sha384-prf.c"
"src/crypto/md4-internal.c"
"src/crypto/sha1-tprf.c"
"src/eap_common/eap_wsc_common.c"
"src/eap_peer/chap.c"
"src/eap_peer/eap.c"
"src/eap_peer/eap_common.c"
@@ -51,9 +52,8 @@ set(srcs "port/os_xtensa.c"
"src/wps/wps_attr_process.c"
"src/wps/wps_common.c"
"src/wps/wps_dev_attr.c"
"src/wps/wps_enrollee.c"
"src/wps/wps_registrar.c"
"src/wps/wps_validate.c")
"src/wps/wps_enrollee.c")
# "src/wps/wps_registrar.c")
set(esp_srcs "esp_supplicant/src/esp_wpa2.c"
"esp_supplicant/src/esp_wpa_main.c"
@@ -66,7 +66,7 @@ if(CONFIG_ESP_WIFI_SOFTAP_SUPPORT)
endif()
if(CONFIG_WPA_MBEDTLS_CRYPTO)
set(tls_src "src/crypto/tls_mbedtls.c")
set(tls_src "esp_supplicant/src/crypto/tls_mbedtls.c")
else()
set(tls_src
"src/tls/asn1.c"
@@ -91,9 +91,9 @@ endif()
if(CONFIG_WPA_MBEDTLS_CRYPTO)
set(crypto_src
"src/crypto/crypto_mbedtls.c"
"src/crypto/crypto_mbedtls-bignum.c"
"src/crypto/crypto_mbedtls-ec.c")
"esp_supplicant/src/crypto/crypto_mbedtls.c"
"esp_supplicant/src/crypto/crypto_mbedtls-bignum.c"
"esp_supplicant/src/crypto/crypto_mbedtls-ec.c")
# Add internal RC4 if RC4 is disabled in mbedtls
if(CONFIG_MBEDTLS_RC4_DISABLED)
set(crypto_src ${crypto_src} "src/crypto/rc4.c")
@@ -133,7 +133,6 @@ else()
"src/crypto/crypto_internal-cipher.c"
"src/crypto/crypto_internal-modexp.c"
"src/crypto/crypto_internal-rsa.c"
"src/crypto/crypto_mbedtls-rsa.c"
"src/crypto/crypto_internal.c"
"src/crypto/des-internal.c"
"src/crypto/md4-internal.c"
@@ -180,7 +179,7 @@ endif()
idf_component_register(SRCS "${srcs}" ${esp_srcs} "${tls_src}" "${roaming_src}"
"${crypto_src}" "${mbo_src}" "${dpp_src}"
INCLUDE_DIRS include port/include esp_supplicant/include
PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src
PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto
PRIV_REQUIRES mbedtls esp_timer)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing -Wno-write-strings -Werror)

View File

@@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_WPS_H__
#define __ESP_WPS_H__

View File

@@ -1,18 +1,7 @@
/*
* Copyright (C) Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License.
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef ESP_PLATFORM

View File

@@ -40,6 +40,7 @@
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
#include "esp_crt_bundle.h"
#endif
#include "esp_wpas_glue.h"
#define WPA2_VERSION "v2.0"
@@ -297,74 +298,6 @@ int wpa2_post(uint32_t sig, uint32_t par)
#endif /* USE_WPA2_TASK */
static void wpa2_sendto_wrapper(void *buffer, uint16_t len)
{
esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
}
static inline int wpa2_sm_ether_send(struct eap_sm *sm, const u8 *dest, u16 proto,
const u8 *data, size_t data_len)
{
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
struct l2_ethhdr *eth = NULL;
if (!buffer) {
wpa_printf(MSG_ERROR, "wpa2: invalid data");
return ESP_FAIL;
} else {
eth = (struct l2_ethhdr *)buffer;
memcpy(eth->h_dest, dest, ETH_ALEN);
memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
eth->h_proto = host_to_be16(proto);
wpa2_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
}
return ESP_OK;
}
u8 *wpa2_sm_alloc_eapol(struct eap_sm *sm, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos)
{
void *buffer;
struct ieee802_1x_hdr *hdr;
*msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
/* XXX: reserve l2_ethhdr is enough */
buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
if (buffer == NULL) {
return NULL;
}
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
hdr->version = 0x01;
hdr->type = type;
hdr->length = host_to_be16(data_len);
if (data) {
memcpy(hdr + 1, data, data_len);
} else {
memset(hdr + 1, 0, data_len);
}
if (data_pos) {
*data_pos = hdr + 1;
}
return (u8 *) hdr;
}
void wpa2_sm_free_eapol(u8 *buffer)
{
if (buffer != NULL) {
buffer = buffer - sizeof(struct l2_ethhdr);
os_free(buffer);
}
}
int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
{
size_t outlen;
@@ -379,15 +312,15 @@ int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
return WPA_ERR_INVALID_BSSID;
}
outbuf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET,
outbuf = wpa_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET,
wpabuf_head_u8(resp), wpabuf_len(resp),
&outlen, NULL);
if (!outbuf) {
return ESP_ERR_NO_MEM;
}
ret = wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
wpa2_sm_free_eapol(outbuf);
ret = wpa_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
wpa_free_eapol(outbuf);
if (ret) {
return ESP_FAIL;
}
@@ -718,14 +651,14 @@ static int wpa2_start_eapol_internal(void)
return WPA_ERR_INVALID_BSSID;
}
buf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, &len, NULL);
buf = wpa_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, &len, NULL);
if (!buf) {
return ESP_FAIL;
}
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
wpa2_sm_free_eapol(buf);
wpa_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
wpa_free_eapol(buf);
return ESP_OK;
}

View File

@@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef ESP_SUPPLICANT
@@ -19,8 +11,10 @@
#include "common/eapol_common.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h"
#include "esp_wpas_glue.h"
#include "esp_private/wifi.h"
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
u8 *wpa_alloc_eapol(void *sm, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos)
{
@@ -38,7 +32,7 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
/* XXX: reserve l2_ethhdr is enough */
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
hdr->version = sm->eapol_version;
hdr->version = DEFAULT_EAPOL_VERSION;
hdr->type = type;
hdr->length = host_to_be16(data_len);
@@ -55,12 +49,42 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
return (u8 *) hdr;
}
void wpa_sm_free_eapol(u8 *buffer)
void wpa_free_eapol(u8 *buffer)
{
if (!buffer) {
return;
}
buffer = buffer - sizeof(struct l2_ethhdr);
os_free(buffer);
}
int wpa_ether_send(void *ctx, const u8 *dest, u16 proto,
const u8 *data, size_t data_len)
{
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
os_memcpy(eth->h_dest, dest, ETH_ALEN);
os_memcpy(eth->h_source, gWpaSm.own_addr, ETH_ALEN);
eth->h_proto = host_to_be16(proto);
esp_wifi_internal_tx(WIFI_IF_STA, buffer, sizeof(struct l2_ethhdr) + data_len);
return ESP_OK;
}
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos)
{
return wpa_alloc_eapol(sm, type, data, data_len, msg_len, data_pos);
}
void wpa_sm_free_eapol(u8 *buffer)
{
return wpa_free_eapol(buffer);
}
void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code)
{

View File

@@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef WPAS_GLUE_H
#define WPAS_GLUE_H
@@ -30,4 +22,13 @@ int wpa_sm_get_beacon_ie(struct wpa_sm *sm);
void wpa_sm_free_eapol(u8 *buffer);
u8 *wpa_alloc_eapol(void *sm, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos);
void wpa_free_eapol(u8 *buffer);
int wpa_ether_send(void *ctx, const u8 *dest, u16 proto,
const u8 *data, size_t data_len);
#endif /* WPAS_GLUE_H */

View File

@@ -26,6 +26,10 @@
#include "esp_wifi.h"
#include "esp_err.h"
#include "esp_private/wifi.h"
#include "esp_wps_i.h"
#include "esp_wps.h"
#include "eap_common/eap_wsc_common.h"
#include "esp_wpas_glue.h"
#define API_MUTEX_TAKE() do {\
if (!s_wps_api_lock) {\
@@ -281,33 +285,26 @@ int wps_post(uint32_t sig, uint32_t par)
}
#endif
static void wps_sendto_wrapper(void *buffer, uint16_t len)
{
esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
}
/*
* wps_sm_ether_send - Send Ethernet frame
* @wpa_s: Pointer to wpa_supplicant data
* @dest: Destination MAC address
* @proto: Ethertype in host byte order
* @buf: Frame payload starting from IEEE 802.1X header
* @len: Frame payload length
* Returns: >=0 on success, <0 on failure
*/
static inline int wps_sm_ether_send(struct wps_sm *sm, const u8 *dest, u16 proto,
static inline int wps_sm_ether_send(struct wps_sm *sm, u16 proto,
const u8 *data, size_t data_len)
{
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
u8 bssid[ETH_ALEN];
int ret = esp_wifi_get_assoc_bssid_internal(bssid);
os_memcpy(eth->h_dest, dest, ETH_ALEN);
os_memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
eth->h_proto = host_to_be16(proto);
if (ret != 0) {
wpa_printf(MSG_ERROR, "bssid is empty!");
return -1;
}
wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
return ESP_OK;
return wpa_ether_send(sm, bssid, proto, data, data_len);
}
@@ -315,189 +312,13 @@ u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos)
{
void *buffer;
struct ieee802_1x_hdr *hdr;
*msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
/* XXX: reserve l2_ethhdr is enough */
buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
if (buffer == NULL) {
return NULL;
}
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
hdr->version = sm->eapol_version;
hdr->type = type;
hdr->length = host_to_be16(data_len);
if (data) {
os_memcpy(hdr + 1, data, data_len);
} else {
os_memset(hdr + 1, 0, data_len);
}
if (data_pos) {
*data_pos = hdr + 1;
}
return (u8 *) hdr;
return wpa_alloc_eapol(sm, type, data, data_len, msg_len, data_pos);
}
void wps_sm_free_eapol(u8 *buffer)
{
if (buffer != NULL) {
buffer = buffer - sizeof(struct l2_ethhdr);
os_free(buffer);
}
}
/**
* wps_init - Initialize WPS Registration protocol data
* @cfg: WPS configuration
* Returns: Pointer to allocated data or %NULL on failure
*
* This function is used to initialize WPS data for a registration protocol
* instance (i.e., each run of registration protocol as a Registrar of
* Enrollee. The caller is responsible for freeing this data after the
* registration run has been completed by calling wps_deinit().
*/
struct wps_data *wps_init(void)
{
struct wps_sm *sm = gWpsSm;
struct wps_data *data = (struct wps_data *)os_zalloc(sizeof(*data));
const char *all_zero_pin = "00000000";
if (data == NULL) {
return NULL;
}
data->wps = sm->wps_ctx;
if (IS_WPS_REGISTRAR(wps_get_type())) {
data->registrar = 1;
} else {
data->registrar = 0;
}
data->registrar = 0; /* currently, we force to support enrollee only */
if (data->registrar) {
os_memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN);
} else {
os_memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN);
os_memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN);
}
if (wps_get_type() == WPS_TYPE_PIN) {
u32 spin = 0;
data->dev_pw_id = DEV_PW_DEFAULT;
data->dev_password_len = 8;
data->dev_password = (u8 *) os_zalloc(data->dev_password_len + 1);
if (data->dev_password == NULL) {
os_free(data);
return NULL;
}
spin = wps_generate_pin();
sprintf((char *)data->dev_password, "%08d", spin);
wpa_hexdump_key(MSG_DEBUG, "WPS: AP PIN dev_password",
data->dev_password, data->dev_password_len);
do {
char tmpp[9];
os_bzero(tmpp, 9);
os_memcpy(tmpp, data->dev_password, 8);
wpa_printf(MSG_DEBUG, "WPS PIN [%s]", tmpp);
wifi_event_sta_wps_er_pin_t evt;
os_memcpy(evt.pin_code, data->dev_password, 8);
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), portMAX_DELAY);
} while (0);
} else if (wps_get_type() == WPS_TYPE_PBC) {
data->pbc = 1;
/* Use special PIN '00000000' for PBC */
data->dev_pw_id = DEV_PW_PUSHBUTTON;
if (data->dev_password) {
os_free(data->dev_password);
}
data->dev_password = (u8 *) os_zalloc(9);
if (data->dev_password == NULL) {
os_free(data);
return NULL;
} else {
strncpy((char *)data->dev_password, all_zero_pin, 9);
}
data->dev_password_len = 8;
}
#ifdef CONFIG_WPS_NFC
if (cfg->wps->ap && !cfg->registrar && cfg->wps->ap_nfc_dev_pw_id) {
data->dev_pw_id = cfg->wps->ap_nfc_dev_pw_id;
os_free(data->dev_password);
data->dev_password =
os_malloc(wpabuf_len(cfg->wps->ap_nfc_dev_pw));
if (data->dev_password == NULL) {
os_free(data);
return NULL;
}
os_memcpy(data->dev_password,
wpabuf_head(cfg->wps->ap_nfc_dev_pw),
wpabuf_len(cfg->wps->ap_nfc_dev_pw));
data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw);
}
#endif /* CONFIG_WPS_NFC */
data->wps->config_methods = WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY;
#ifdef CONFIG_WPS2
data->wps->config_methods |= (WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_DISPLAY);
#endif
data->state = data->registrar ? RECV_M1 : SEND_M1;
return data;
}
/**
* wps_deinit - Deinitialize WPS Registration protocol data
* @data: WPS Registration protocol data from wps_init()
*/
void wps_deinit(void)
{
struct wps_data *data = gWpsSm->wps;
#ifdef CONFIG_WPS_NFC
if (data->registrar && data->nfc_pw_token)
wps_registrar_remove_nfc_pw_token(data->wps->registrar,
data->nfc_pw_token);
#endif /* CONFIG_WPS_NFC */
if (data->wps_pin_revealed) {
wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
"negotiation failed");
} else if (data->registrar)
wpa_printf(MSG_DEBUG, "WPS: register information revealed and "
"negotiation failed");
wpabuf_free(data->dh_privkey);
#ifdef DESP32_WORKAROUND
/*
* due to the public key calculated when wps start, it will not calculate anymore even when we build M1 message, also calculate the key need take a long time
* which would cause WPS fail, so we clean the key after WPS finished .
*/
data->dh_privkey = NULL;
#endif //DESP32_WORKAROUND
wpabuf_free(data->dh_pubkey_e);
wpabuf_free(data->dh_pubkey_r);
wpabuf_free(data->last_msg);
os_free(data->dev_password);
dh5_free(data->dh_ctx);
wps_dev_deinit(&data->peer_dev);
#ifdef CONFIG_WPS_NFC
os_free(data->nfc_pw_token);
#endif
os_free(data);
return wpa_free_eapol(buffer);
}
static void
@@ -506,20 +327,17 @@ wps_build_ic_appie_wps_pr(void)
struct wpabuf *extra_ie = NULL;
struct wpabuf *wps_ie;
struct wps_sm *sm = gWpsSm;
u16 pw_id;
wpa_printf(MSG_DEBUG, "wps build: wps pr");
if (wps_get_type() == WPS_TYPE_PBC) {
wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_PUSHBUTTON,
sm->dev,
sm->uuid, WPS_REQ_ENROLLEE,
0, NULL);
pw_id = DEV_PW_PUSHBUTTON;
} else {
wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_DEFAULT,
sm->dev,
sm->uuid, WPS_REQ_ENROLLEE,
0, NULL);
pw_id = DEV_PW_DEFAULT;
}
wps_ie = wps_build_probe_req_ie(pw_id, sm->dev, sm->uuid,
WPS_REQ_ENROLLEE, 0, NULL);
if (!wps_ie) {
return;
@@ -540,7 +358,7 @@ wps_build_ic_appie_wps_pr(void)
static void
wps_build_ic_appie_wps_ar(void)
{
struct wpabuf *buf = (struct wpabuf *)wps_build_assoc_req_ie(WPS_REQ_ENROLLEE);
struct wpabuf *buf = wps_build_assoc_req_ie(WPS_REQ_ENROLLEE);
wpa_printf(MSG_DEBUG, "wps build: wps ar");
@@ -555,13 +373,6 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
{
struct wps_sm *sm = gWpsSm;
wifi_mode_t op_mode = 0;
#ifdef WPS_DEBUG
char tmp[32];
os_bzero(tmp, 32);
strncpy(tmp, (char *)&scan->ssid[2], (int)scan->ssid[1]);
wpa_printf(MSG_DEBUG, "wps parse scan: %s", tmp);
#endif
if (!sm->is_wps_scan || !scan->bssid) {
return false;
@@ -574,22 +385,26 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
return false;
}
if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) {
esp_wifi_get_mode(&op_mode);
if ((op_mode != WIFI_MODE_STA)
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
&& (op_mode != WIFI_MODE_APSTA)
#endif
) {
return false;
}
if (!scan->rsn && !scan->wpa && (scan->capinfo & WLAN_CAPABILITY_PRIVACY)) {
wpa_printf(MSG_INFO, "WEP not suppported in WPS");
return false;
}
if (sm->wps_pin_war) {
if (sm->ignore_sel_reg && !is_zero_ether_addr(sm->bssid)) {
/* We have selected candidate for this scan */
return false;
}
esp_wifi_get_mode(&op_mode);
if ((op_mode == WIFI_MODE_STA
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|| op_mode == WIFI_MODE_APSTA
#endif
) && scan->wps) {
if (scan->wps) {
bool ap_found = false;
struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
int count;
@@ -601,11 +416,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
sm->discard_ap_cnt = 0;
ap_found = true;
}
if ((op_mode == WIFI_MODE_STA
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|| op_mode == WIFI_MODE_APSTA
#endif
) && wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
if (wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
/* AP is in discard list? */
for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) {
@@ -613,22 +424,21 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
return false;
}
}
sm->wps_pin_war = true;
}
if (ap_found || sm->wps_pin_war) {
if (ap_found || sm->ignore_sel_reg) {
wpabuf_free(buf);
esp_wifi_enable_sta_privacy_internal();
os_memset(sm->config.ssid, 0, sizeof(sm->config.ssid));
strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
if (scan->bssid && memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0) {
printf("sm BSSid: "MACSTR " scan BSSID " MACSTR "\n", MAC2STR(sm->config.bssid), MAC2STR(scan->bssid));
os_memset(sm->ssid[0], 0, SSID_MAX_LEN);
strncpy((char *)sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]);
sm->ssid_len[0] = scan->ssid[1];
if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR "\n",
MAC2STR(sm->bssid), MAC2STR(scan->bssid));
sm->discover_ssid_cnt++;
os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
os_memcpy(sm->config.bssid, scan->bssid, ETH_ALEN);
sm->config.bssid_set = 1;
}
wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid);
wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->ssid);
sm->channel = scan->chan;
return true;
@@ -643,7 +453,6 @@ int wps_send_eap_identity_rsp(u8 id)
{
struct wps_sm *sm = gWpsSm;
struct wpabuf *eap_buf = NULL;
u8 bssid[6];
u8 *buf = NULL;
int len;
int ret = ESP_OK;
@@ -656,12 +465,6 @@ int wps_send_eap_identity_rsp(u8 id)
goto _err;
}
ret = esp_wifi_get_assoc_bssid_internal(bssid);
if (ret != 0) {
wpa_printf(MSG_ERROR, "bssid is empty!");
ret = ESP_FAIL;
goto _err;
}
wpabuf_put_data(eap_buf, sm->identity, sm->identity_len);
@@ -671,7 +474,7 @@ int wps_send_eap_identity_rsp(u8 id)
goto _err;
}
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
if (ret) {
ret = ESP_FAIL;
goto _err;
@@ -687,11 +490,9 @@ int wps_send_frag_ack(u8 id)
{
struct wps_sm *sm = gWpsSm;
struct wpabuf *eap_buf = NULL;
u8 bssid[6];
u8 *buf;
int len;
int ret = 0;
enum wsc_op_code opcode = WSC_FRAG_ACK;
wpa_printf(MSG_DEBUG, "send frag ack id:%d", id);
@@ -699,28 +500,19 @@ int wps_send_frag_ack(u8 id)
return ESP_FAIL;
}
ret = esp_wifi_get_assoc_bssid_internal(bssid);
if (ret != 0) {
wpa_printf(MSG_ERROR, "bssid is empty!");
return ret;
}
eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, 2, EAP_CODE_RESPONSE, id);
eap_buf = eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE);
if (!eap_buf) {
ret = ESP_ERR_NO_MEM;
goto _err;
}
wpabuf_put_u8(eap_buf, opcode);
wpabuf_put_u8(eap_buf, 0x00); /* flags */
buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
if (!buf) {
ret = ESP_ERR_NO_MEM;
goto _err;
}
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
wps_sm_free_eapol(buf);
if (ret) {
ret = ESP_ERR_NO_MEM;
@@ -859,7 +651,6 @@ int wps_send_wps_mX_rsp(u8 id)
struct wps_sm *sm = gWpsSm;
struct wpabuf *eap_buf = NULL;
struct wpabuf *wps_buf = NULL;
u8 bssid[6];
u8 *buf;
int len;
int ret = 0;
@@ -871,13 +662,7 @@ int wps_send_wps_mX_rsp(u8 id)
return ESP_FAIL;
}
ret = esp_wifi_get_assoc_bssid_internal(bssid);
if (ret != 0) {
wpa_printf(MSG_ERROR, "bssid is empty!");
return ret;
}
wps_buf = (struct wpabuf *)wps_enrollee_get_msg(sm->wps, &opcode);
wps_buf = wps_enrollee_get_msg(sm->wps, &opcode);
if (!wps_buf) {
ret = ESP_FAIL;
goto _err;
@@ -902,7 +687,7 @@ int wps_send_wps_mX_rsp(u8 id)
goto _err;
}
ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
ret = wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
wps_sm_free_eapol(buf);
if (ret) {
ret = ESP_FAIL;
@@ -919,16 +704,8 @@ _err:
int wps_tx_start(void)
{
struct wps_sm *sm = gWpsSm;
u8 bssid[6];
u8 *buf;
int len;
int ret = 0;
ret = esp_wifi_get_assoc_bssid_internal(bssid);
if (ret != 0) {
wpa_printf(MSG_ERROR, "bssid is empty!");
return ret;
}
if (!sm) {
return ESP_FAIL;
@@ -940,7 +717,7 @@ int wps_tx_start(void)
return ESP_ERR_NO_MEM;
}
wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
wps_sm_ether_send(sm, ETH_P_EAPOL, buf, len);
wps_sm_free_eapol(buf);
ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0);
@@ -958,6 +735,30 @@ int wps_start_pending(void)
return wps_tx_start();
}
static void wps_stop_connection_timers(struct wps_sm *sm)
{
esp_wifi_disarm_sta_connection_timer_internal();
ets_timer_disarm(&sm->wps_msg_timeout_timer);
ets_timer_disarm(&sm->wps_success_cb_timer);
}
static int wps_sm_init(struct wps_sm *sm)
{
if (!sm) {
return -1;
}
sm->ignore_sel_reg = false;
sm->discard_ap_cnt = 0;
sm->scan_cnt = 0;
sm->discover_ssid_cnt = 0;
os_bzero(sm->bssid, ETH_ALEN);
os_bzero(sm->ssid, sizeof(sm->ssid));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
sm->ap_cred_cnt = 0;
return 0;
}
int wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)
{
struct wps_sm *sm = gWpsSm;
@@ -967,19 +768,10 @@ int wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)
}
wps_set_status(WPS_STATUS_DISABLE);
sm->scan_cnt = 0;
sm->discover_ssid_cnt = 0;
wps_sm_init(sm);
sm->wps->state = SEND_M1;
os_bzero(sm->bssid, ETH_ALEN);
os_bzero(sm->ssid, sizeof(sm->ssid));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
os_bzero((u8 *)&sm->config, sizeof(wifi_sta_config_t));
sm->ap_cred_cnt = 0;
esp_wifi_disarm_sta_connection_timer_internal();
ets_timer_disarm(&sm->wps_msg_timeout_timer);
ets_timer_disarm(&sm->wps_success_cb_timer);
wps_stop_connection_timers(sm);
esp_wifi_disconnect();
wpa_printf(MSG_DEBUG, "Write wps_fail_information");
@@ -999,23 +791,17 @@ int wps_finish(void)
}
if (sm->wps->state == WPS_FINISHED) {
wpa_printf(MSG_DEBUG, "wps finished------>");
wps_set_status(WPS_STATUS_SUCCESS);
esp_wifi_disarm_sta_connection_timer_internal();
ets_timer_disarm(&sm->wps_timeout_timer);
ets_timer_disarm(&sm->wps_msg_timeout_timer);
wps_stop_connection_timers(sm);
if (sm->ap_cred_cnt == 1) {
wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t));
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
if (config == NULL) {
wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY);
return ESP_FAIL;
}
os_memset(config, 0x00, sizeof(wifi_sta_config_t));
os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]);
os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
@@ -1023,20 +809,19 @@ int wps_finish(void)
esp_wifi_set_config(0, config);
os_free(config);
config = NULL;
}
ets_timer_disarm(&sm->wps_success_cb_timer);
ets_timer_arm(&sm->wps_success_cb_timer, 1000, 0);
ret = 0;
} else {
wpa_printf(MSG_ERROR, "wps failed-----> wps_pin_war=%d", sm->wps_pin_war);
if (sm->wps_pin_war) {
wpa_printf(MSG_ERROR, "wps failed-----> ignore_sel_reg=%d", sm->ignore_sel_reg);
if (sm->ignore_sel_reg) {
sm->discover_ssid_cnt = 0;
esp_wifi_disconnect();
os_bzero(sm->ssid, sizeof(sm->ssid));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
wps_add_discard_ap(sm->config.bssid);
wps_add_discard_ap(sm->bssid);
} else {
ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
}
@@ -1063,7 +848,7 @@ void wps_add_discard_ap(u8 *bssid)
}
sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM;
}
os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6);
os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, ETH_ALEN);
wpa_printf(MSG_INFO, "Added BSSID:"MACSTR" to discard list cnt=%d" , MAC2STR(bssid), sm->discard_ap_cnt);
}
@@ -1118,13 +903,13 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
#ifdef USE_WPS_TASK
{
struct wps_rx_param *param = (struct wps_rx_param *)os_zalloc(sizeof(struct wps_rx_param)); /* free in task */
struct wps_rx_param *param = os_zalloc(sizeof(struct wps_rx_param)); /* free in task */
if (!param) {
return ESP_ERR_NO_MEM;
}
param->buf = (u8 *)os_zalloc(len); /* free in task */
param->buf = os_zalloc(len); /* free in task */
if (!param->buf) {
os_free(param);
return ESP_ERR_NO_MEM;
@@ -1281,8 +1066,7 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
break;
}
out:
if (ret != 0 && sm->wps_pin_war) {
sm->wps_pin_war = false;
if (ret != 0 && sm->ignore_sel_reg) {
wifi_wps_scan();
} else if ((ret != 0 || res == WPS_FAILURE)) {
wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
@@ -1381,35 +1165,35 @@ int wps_dev_init(void)
}
}
dev->manufacturer = (char *)os_zalloc(WPS_MAX_MANUFACTURER_LEN);
dev->manufacturer = os_zalloc(WPS_MAX_MANUFACTURER_LEN);
if (!dev->manufacturer) {
ret = ESP_FAIL;
goto _out;
}
sprintf(dev->manufacturer, s_factory_info->manufacturer);
dev->model_name = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN);
dev->model_name = os_zalloc(WPS_MAX_MODEL_NAME_LEN);
if (!dev->model_name) {
ret = ESP_FAIL;
goto _out;
}
sprintf(dev->model_name, s_factory_info->model_name);
dev->model_number = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN);
dev->model_number = os_zalloc(WPS_MAX_MODEL_NAME_LEN);
if (!dev->model_number) {
ret = ESP_FAIL;
goto _out;
}
sprintf(dev->model_number, s_factory_info->model_number);
dev->device_name = (char *)os_zalloc(WPS_MAX_DEVICE_NAME_LEN);
dev->device_name = os_zalloc(WPS_MAX_DEVICE_NAME_LEN);
if (!dev->device_name) {
ret = ESP_FAIL;
goto _out;
}
sprintf(dev->device_name, s_factory_info->device_name);
dev->serial_number = (char *)os_zalloc(16);
dev->serial_number = os_zalloc(16);
if (!dev->serial_number) {
ret = ESP_FAIL;
goto _out;
@@ -1424,30 +1208,7 @@ int wps_dev_init(void)
return ESP_OK;
_out:
if (!dev) {
return ret;
}
if (dev->manufacturer) {
os_free(dev->manufacturer);
}
if (dev->model_name) {
os_free(dev->model_name);
}
if (dev->model_number) {
os_free(dev->model_number);
}
if (dev->device_name) {
os_free(dev->device_name);
}
if (dev->serial_number) {
os_free(dev->serial_number);
}
if (s_factory_info) {
os_free(s_factory_info);
s_factory_info = NULL;
}
wps_dev_deinit(dev);
return ret;
}
@@ -1524,17 +1285,16 @@ wifi_station_wps_msg_timeout_internal(void)
return;
} else if (sm->wps->state == RECV_M2) {
wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>");
if (!sm->wps_pin_war) {
if (!sm->ignore_sel_reg) {
wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
}
}
if (sm->wps_pin_war) {
if (sm->ignore_sel_reg) {
esp_wifi_disconnect();
wps_add_discard_ap(sm->config.bssid);
sm->wps_pin_war = false;
wps_add_discard_ap(sm->bssid);
os_bzero(sm->ssid, sizeof(sm->ssid));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
os_bzero(sm->bssid, ETH_ALEN);
sm->discover_ssid_cnt = 0;
wifi_wps_scan();
}
@@ -1557,7 +1317,7 @@ void wifi_station_wps_success_internal(void)
int i;
/*
* For only one AP credential don't sned event data, wps_finish() has already set
* For only one AP credential don't send event data, wps_finish() has already set
* the config. This is for backward compatibility.
*/
if (sm->ap_cred_cnt > 1) {
@@ -1600,12 +1360,35 @@ void wifi_station_wps_eapol_start_handle(void)
#endif
}
static int save_credentials_cb(void *ctx, const struct wps_credential *cred)
{
if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > 2) {
return ESP_FAIL;
}
os_memset(gWpsSm->ssid[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->ssid[gWpsSm->ap_cred_cnt]));
os_memset(gWpsSm->key[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->key[gWpsSm->ap_cred_cnt]));
os_memcpy(gWpsSm->ssid[gWpsSm->ap_cred_cnt], cred->ssid, cred->ssid_len);
gWpsSm->ssid_len[gWpsSm->ap_cred_cnt] = cred->ssid_len;
os_memcpy(gWpsSm->key[gWpsSm->ap_cred_cnt], cred->key, cred->key_len);
gWpsSm->key_len[gWpsSm->ap_cred_cnt] = cred->key_len;
gWpsSm->ap_cred_cnt++;
wpa_hexdump_ascii(MSG_DEBUG, "ssid ", cred->ssid, cred->ssid_len);
wpa_hexdump_ascii(MSG_DEBUG, "key ", cred->key, cred->key_len);
return ESP_OK;
}
int
wifi_station_wps_init(void)
{
struct wps_funcs *wps_cb;
struct wps_sm *sm = NULL;
uint8_t mac[6];
struct wps_config cfg = {0};
if (gWpsSm) {
goto _out;
@@ -1613,30 +1396,20 @@ wifi_station_wps_init(void)
wpa_printf(MSG_DEBUG, "wifi sta wps init");
gWpsSm = (struct wps_sm *)os_zalloc(sizeof(struct wps_sm)); /* alloc Wps_sm */
gWpsSm = os_zalloc(sizeof(struct wps_sm)); /* alloc Wps_sm */
if (!gWpsSm) {
goto _out;
}
sm = gWpsSm;
os_memset(sm, 0x00, sizeof(struct wps_sm));
esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac);
os_memcpy(sm->ownaddr, mac, ETH_ALEN);
sm->discover_ssid_cnt = 0;
sm->ignore_sel_reg = false;
sm->discard_ap_cnt = 0;
os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
os_memset(&sm->config, 0x00, sizeof(wifi_sta_config_t));
sm->eapol_version = 0x1;
sm->identity_len = 29;
os_memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len);
sm->wps_pin_war = false;
sm->identity_len = WSC_ID_ENROLLEE_LEN;
os_memcpy(sm->identity, WSC_ID_ENROLLEE, sm->identity_len);
sm->is_wps_scan = false;
sm->wps_ctx = (struct wps_context *)os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
sm->wps_ctx = os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
if (!sm->wps_ctx) {
goto _err;
}
@@ -1645,10 +1418,42 @@ wifi_station_wps_init(void)
goto _err;
}
if ((sm->wps = wps_init()) == NULL) { /* alloc wps_data */
cfg.wps = sm->wps_ctx;
if (IS_WPS_REGISTRAR(wps_get_type())) {
cfg.registrar = 1;
}
/* TODO add for Registrar */
if (wps_get_type() == WPS_TYPE_PIN) {
unsigned int spin = 0;
cfg.dev_pw_id = DEV_PW_DEFAULT;
cfg.pin_len = 8;
cfg.pin = os_zalloc(cfg.pin_len + 1);
if (!cfg.pin) {
goto _err;
}
if (wps_generate_pin(&spin) < 0) {
goto _err;
}
os_sprintf((char *)cfg.pin, "%08d", spin);
} else if (wps_get_type() == WPS_TYPE_PBC) {
cfg.pbc = 1;
}
if ((sm->wps = wps_init(&cfg)) == NULL) { /* alloc wps_data */
goto _err;
}
if (cfg.pin) {
os_free((u8 *)cfg.pin);
}
if (wps_get_type() == WPS_TYPE_PIN) {
wifi_event_sta_wps_er_pin_t evt;
os_memcpy(evt.pin_code, sm->wps->dev_password, 8);
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), portMAX_DELAY);
}
sm->wps->wps->cred_cb = save_credentials_cb;
/**************80211 reference***************/
if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_PR) == NULL) { /* alloc probe req wps ie */
@@ -1670,8 +1475,6 @@ wifi_station_wps_init(void)
ets_timer_disarm(&sm->wps_eapol_start_timer);
ets_timer_setfn(&sm->wps_eapol_start_timer, (ETSTimerFunc *)wifi_station_wps_eapol_start_handle, NULL);
sm->scan_cnt = 0;
wps_cb = os_malloc(sizeof(struct wps_funcs));
if (wps_cb == NULL) {
goto _err;
@@ -1698,7 +1501,7 @@ _err:
sm->wps_ctx = NULL;
}
if (sm->wps) {
wps_deinit();
wps_deinit(sm->wps);
sm->wps = NULL;
}
os_free(gWpsSm);
@@ -1752,7 +1555,7 @@ wifi_station_wps_deinit(void)
sm->wps_ctx = NULL;
}
if (sm->wps) {
wps_deinit();
wps_deinit(sm->wps);
sm->wps = NULL;
}
os_free(gWpsSm);
@@ -1761,73 +1564,17 @@ wifi_station_wps_deinit(void)
return ESP_OK;
}
int
wps_station_wps_register_cb(wps_st_cb_t cb)
{
if (!gWpsSm) {
return ESP_FAIL;
}
gWpsSm->st_cb = cb;
return ESP_OK;
}
struct wps_sm *
wps_sm_get(void)
{
return gWpsSm;
}
int
wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx)
{
u8 *tmpssid;
if (!ssid || !gWpsSm || idx > 2) {
return ESP_FAIL;
}
os_memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx]));
os_memcpy(gWpsSm->ssid[idx], ssid, ssid_len);
gWpsSm->ssid_len[idx] = ssid_len;
gWpsSm->ap_cred_cnt++;
tmpssid = (u8 *)os_zalloc(ssid_len + 1);
if (tmpssid) {
os_memcpy(tmpssid, ssid, ssid_len);
wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid);
os_free(tmpssid);
}
return ESP_OK;
}
int
wps_key_save(char *key, u8 key_len, u8 idx)
{
u8 *tmpkey;
if (!key || !gWpsSm || idx > 2) {
return ESP_FAIL;
}
os_memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx]));
os_memcpy(gWpsSm->key[idx], key, key_len);
gWpsSm->key_len[idx] = key_len;
tmpkey = (u8 *)os_zalloc(key_len + 1);
if (tmpkey) {
os_memcpy(tmpkey, key, key_len);
wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx);
os_free(tmpkey);
}
return ESP_OK;
}
void
wifi_wps_scan_done(void *arg, STATUS status)
{
struct wps_sm *sm = gWpsSm;
wifi_config_t wifi_config;
wifi_config_t wifi_config = {0};
wpa_printf(MSG_INFO, "WPS: scan done");
if (wps_get_type() == WPS_TYPE_DISABLE) {
@@ -1855,7 +1602,11 @@ wifi_wps_scan_done(void *arg, STATUS status)
if (wps_get_status() == WPS_STATUS_PENDING) {
esp_wifi_disconnect();
os_memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t));
os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN);
os_strncpy((char *)wifi_config.sta.ssid, (char *)sm->ssid[0], sm->ssid_len[0]);
wifi_config.sta.bssid_set = 1;
wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR,
(char *)sm->ssid[0], MAC2STR(wifi_config.sta.bssid));
esp_wifi_set_config(0, &wifi_config);
wpa_printf(MSG_DEBUG, "WPS: neg start");
@@ -1864,8 +1615,8 @@ wifi_wps_scan_done(void *arg, STATUS status)
ets_timer_arm(&sm->wps_msg_timeout_timer, 2000, 0);
} else if (wps_get_status() == WPS_STATUS_SCANNING) {
if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) {
wpa_printf(MSG_INFO, "WPS: ignore selected registrar after %d scans", sm->scan_cnt);
sm->ignore_sel_reg = true;
sm->wps_pin_war = false;
}
ets_timer_arm(&sm->wps_scan_timer, 100, 0);
} else {
@@ -1911,11 +1662,14 @@ int wifi_station_wps_start(void)
case WPS_STATUS_DISABLE: {
sm->is_wps_scan = true;
wps_build_public_key(sm->wps, NULL, WPS_CALC_KEY_PRE_CALC);
wps_build_public_key(sm->wps, NULL);
sm->wps->wps->dh_privkey = wpabuf_dup(sm->wps->dh_privkey);
sm->wps->wps->dh_ctx = sm->wps->dh_ctx;
sm->wps->wps->dh_pubkey = sm->wps->dh_pubkey_e;
sm->wps->wps->rf_band_cb = NULL;
wpabuf_clear_free(sm->wps->dh_privkey);
sm->wps->dh_privkey = NULL;
wifi_wps_scan();
break;
}
case WPS_STATUS_SCANNING:
@@ -2230,24 +1984,3 @@ int esp_wifi_wps_start(int timeout_ms)
API_MUTEX_GIVE();
return ESP_OK;
}
bool
wifi_set_wps_cb(wps_st_cb_t cb)
{
wifi_mode_t mode;
esp_wifi_get_mode(&mode);
if (
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
mode == WIFI_MODE_AP ||
#endif
mode == WIFI_MODE_NULL) {
return false;
}
if (wps_station_wps_register_cb(cb) == 0) {
return true;
}
return false;
}

View File

@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* WPS message flag */
enum wps_msg_flag {
WPS_MSG_FLAG_MORE = 0x01,
WPS_MSG_FLAG_LEN = 0x02
};
#ifdef USE_WPS_TASK
enum wps_sig_type {
SIG_WPS_ENABLE = 1, //1
SIG_WPS_DISABLE, //2
SIG_WPS_START, //3
SIG_WPS_RX, //4
SIG_WPS_TIMER_TIMEOUT, //5
SIG_WPS_TIMER_MSG_TIMEOUT, //6
SIG_WPS_TIMER_SUCCESS_CB, //7
SIG_WPS_TIMER_SCAN, //8
SIG_WPS_TIMER_EAPOL_START, //9
SIG_WPS_NUM, //10
};
#endif
#define WPS_IGNORE_SEL_REG_MAX_CNT 4
#define WPS_MAX_DIS_AP_NUM 10
/* Bssid of the discard AP which is discarded for not select reg or other reason */
struct discard_ap_list_t{
u8 bssid[6];
};
#ifndef MAX_PASSPHRASE_LEN
#define MAX_PASSPHRASE_LEN 64
#endif
#define WPS_OUTBUF_SIZE 500
struct wps_sm {
struct wps_config *wps_cfg;
struct wps_context *wps_ctx;
struct wps_data *wps;
char identity[32];
u8 identity_len;
u8 ownaddr[ETH_ALEN];
u8 bssid[ETH_ALEN];
u8 ssid[MAX_CRED_COUNT][SSID_MAX_LEN];
u8 ssid_len[MAX_CRED_COUNT];
char key[MAX_CRED_COUNT][MAX_PASSPHRASE_LEN];
u8 key_len[MAX_CRED_COUNT];
u8 ap_cred_cnt;
struct wps_device_data *dev;
u8 uuid[16];
ETSTimer wps_timeout_timer;
ETSTimer wps_msg_timeout_timer;
ETSTimer wps_scan_timer;
ETSTimer wps_success_cb_timer;
ETSTimer wps_eapol_start_timer;
u8 current_identifier;
bool is_wps_scan;
u8 channel;
u8 scan_cnt;
#ifdef USE_WPS_TASK
u8 wps_sig_cnt[SIG_WPS_NUM];
#endif
u8 discover_ssid_cnt;
bool ignore_sel_reg;
struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM];
u8 discard_ap_cnt;
};
struct wps_sm *wps_sm_get(void);
int wps_station_wps_unregister_cb(void);
int wps_start_pending(void);
int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
int wps_dev_deinit(struct wps_device_data *dev);

View File

@@ -515,6 +515,12 @@ struct ieee80211_ht_operation {
#define HT_OPER_PARAM_PCO_PHASE ((u16) BIT(11))
/* B36..B39 - Reserved */
#define MULTI_AP_SUB_ELEM_TYPE 0x06
#define MULTI_AP_TEAR_DOWN BIT(4)
#define MULTI_AP_FRONTHAUL_BSS BIT(5)
#define MULTI_AP_BACKHAUL_BSS BIT(6)
#define MULTI_AP_BACKHAUL_STA BIT(7)
#define WMM_OUI_TYPE 2
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1

View File

@@ -354,7 +354,7 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
struct os_reltime now;
if (os_get_reltime(&now) == 0 &&
os_time_expired(&now, &target->last_update,
os_reltime_expired(&now, &target->last_update,
age_secs)) {
wpa_printf(MSG_DEBUG,
"Candidate BSS is more than %jd seconds old",
@@ -546,7 +546,7 @@ static void wnm_add_cand_list(struct wpa_supplicant *wpa_s, struct wpabuf **buf)
* list.
*/
os_get_reltime(&now);
if (os_time_expired(&now, &wpa_s->last_scan, 10))
if (os_reltime_expired(&now, &wpa_s->last_scan, 10))
return;
wpa_printf(MSG_DEBUG,
@@ -1010,7 +1010,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s,
struct os_reltime now;
os_get_reltime(&now);
if (!os_time_expired(&now, &wpa_s->last_scan, 10)) {
if (!os_reltime_expired(&now, &wpa_s->last_scan, 10)) {
wpa_printf(MSG_DEBUG,
"WNM: Try to use recent scan results");
if (wnm_scan_process(wpa_s, 0) > 0)

View File

@@ -0,0 +1,33 @@
/*
* EAP-WSC common routines for Wi-Fi Protected Setup
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "eap_peer/eap_defs.h"
#include "eap_peer/eap_common.h"
#include "wps/wps.h"
#include "eap_wsc_common.h"
struct wpabuf * eap_wsc_build_frag_ack(u8 id, u8 code)
{
struct wpabuf *msg;
msg = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, 2, code, id);
if (msg == NULL) {
wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
"FRAG_ACK");
return NULL;
}
wpa_printf(MSG_DEBUG, "EAP-WSC: Send WSC/FRAG_ACK");
wpabuf_put_u8(msg, WSC_FRAG_ACK); /* Op-Code */
wpabuf_put_u8(msg, 0); /* Flags */
return msg;
}

View File

@@ -0,0 +1,27 @@
/*
* EAP-WSC definitions for Wi-Fi Protected Setup
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef EAP_WSC_COMMON_H
#define EAP_WSC_COMMON_H
#define EAP_VENDOR_TYPE_WSC 1
#define WSC_FLAGS_MF 0x01
#define WSC_FLAGS_LF 0x02
#define WSC_ID_REGISTRAR "WFA-SimpleConfig-Registrar-1-0"
#define WSC_ID_REGISTRAR_LEN 30
#define WSC_ID_ENROLLEE "WFA-SimpleConfig-Enrollee-1-0"
#define WSC_ID_ENROLLEE_LEN 29
#define WSC_FRAGMENT_SIZE 1400
struct wpabuf * eap_wsc_build_frag_ack(u8 id, u8 code);
#endif /* EAP_WSC_COMMON_H */

View File

@@ -38,7 +38,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
{
wpa_bin_clear_free(entry, sizeof(*entry));
bin_clear_free(entry, sizeof(*entry));
}

View File

@@ -191,7 +191,7 @@ static inline int wpa_sm_get_bssid(struct wpa_sm *sm, u8 *bssid)
}
/*
* wpa_ether_send - Send Ethernet frame
* wpa_sm_ether_send - Send Ethernet frame
* @wpa_s: Pointer to wpa_supplicant data
* @dest: Destination MAC address
* @proto: Ethertype in host byte order
@@ -199,18 +199,10 @@ static inline int wpa_sm_get_bssid(struct wpa_sm *sm, u8 *bssid)
* @len: Frame payload length
* Returns: >=0 on success, <0 on failure
*/
static inline int wpa_sm_ether_send( struct wpa_sm *sm, const u8 *dest, u16 proto,
static inline int wpa_sm_ether_send(struct wpa_sm *sm, const u8 *dest, u16 proto,
const u8 *data, size_t data_len)
{
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
memcpy(eth->h_dest, dest, ETH_ALEN);
memcpy(eth->h_source, sm->own_addr, ETH_ALEN);
eth->h_proto = host_to_be16(proto);
sm->sendto(buffer, sizeof(struct l2_ethhdr) + data_len);
return 0;
return wpa_ether_send(sm, dest, proto, data, data_len);
}
/**
@@ -2176,7 +2168,7 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func,
struct wpa_sm *sm = &gWpaSm;
u16 spp_attrubute = 0;
sm->eapol_version = 0x1; /* DEFAULT_EAPOL_VERSION */
sm->eapol_version = DEFAULT_EAPOL_VERSION; /* DEFAULT_EAPOL_VERSION */
sm->sendto = snd_func;
sm->config_assoc_ie = set_assoc_ie_func;
sm->install_ppkey = ppinstallkey;

View File

@@ -19,10 +19,10 @@
#include "wpa_i.h"
struct wpa_sm;
extern struct wpa_sm gWpaSm;
#define WPA_SM_STATE(_sm) ((_sm)->wpa_state)
bool wpa_sta_is_cur_pmksa_set(void);
bool wpa_sta_in_4way_handshake(void);
bool wpa_sta_cur_pmksa_matches_akm(void);

View File

@@ -10,6 +10,8 @@
#define WPA_I_H
extern struct wpa_sm gWpaSm;
#define DEFAULT_EAPOL_VERSION 1
struct install_key {
int keys_cleared;
enum wpa_alg alg;

View File

@@ -1,35 +1,18 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
* Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "includes.h"
#include <limits.h>
#include "utils/common.h"
#include <time.h>
#include "common/ieee802_11_defs.h"
#include "common.h"
/**
* inc_byte_array - Increment arbitrary length byte array by one
* @counter: Pointer to byte array
* @len: Length of the counter in bytes
*
* This function increments the last byte of the counter by one and continues
* rolling over to more significant bytes if the byte was incremented from
* 0xff to 0x00.
*/
void inc_byte_array(u8 *counter, size_t len)
{
int pos = len - 1;
while (pos >= 0) {
counter[pos]++;
if (counter[pos] != 0)
break;
pos--;
}
}
static int hex2num(char c)
{
@@ -56,6 +39,36 @@ int hex2byte(const char *hex)
}
/**
* hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
* @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
* Returns: Characters used (> 0) on success, -1 on failure
*/
int hwaddr_aton2(const char *txt, u8 *addr)
{
int i;
const char *pos = txt;
for (i = 0; i < 6; i++) {
int a, b;
while (*pos == ':' || *pos == '.' || *pos == '-')
pos++;
a = hex2num(*pos++);
if (a < 0)
return -1;
b = hex2num(*pos++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
}
return pos - txt;
}
/**
* hexstr2bin - Convert ASCII hex string into binary data
* @hex: ASCII hex string (e.g., "01ab")
@@ -81,6 +94,28 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len)
return 0;
}
/**
* inc_byte_array - Increment arbitrary length byte array by one
* @counter: Pointer to byte array
* @len: Length of the counter in bytes
*
* This function increments the last byte of the counter by one and continues
* rolling over to more significant bytes if the byte was incremented from
* 0xff to 0x00.
*/
void inc_byte_array(u8 *counter, size_t len)
{
int pos = len - 1;
while (pos >= 0) {
counter[pos]++;
if (counter[pos] != 0)
break;
pos--;
}
}
void wpa_get_ntp_timestamp(u8 *buf)
{
struct os_time now;
@@ -133,7 +168,7 @@ void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
*txt++ = 't';
break;
default:
if (data[i] >= 32 && data[i] <= 127) {
if (data[i] >= 32 && data[i] <= 126) {
*txt++ = data[i];
} else {
txt += os_snprintf(txt, end - txt, "\\x%02x",
@@ -229,6 +264,39 @@ size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
}
/**
* wpa_ssid_txt - Convert SSID to a printable string
* @ssid: SSID (32-octet string)
* @ssid_len: Length of ssid in octets
* Returns: Pointer to a printable string
*
* This function can be used to convert SSIDs into printable form. In most
* cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
* does not limit the used character set, so anything could be used in an SSID.
*
* This function uses a static buffer, so only one call can be used at the
* time, i.e., this is not re-entrant and the returned buffer must be used
* before calling this again.
*/
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
{
static char ssid_txt[SSID_MAX_LEN * 4 + 1];
if (ssid == NULL) {
ssid_txt[0] = '\0';
return ssid_txt;
}
printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
return ssid_txt;
}
void * __hide_aliasing_typecast(void *foo)
{
return foo;
}
char * wpa_config_parse_string(const char *value, size_t *len)
{
@@ -312,6 +380,19 @@ int wpa_is_hex(const u8 *data, size_t len)
}
int has_ctrl_char(const u8 *data, size_t len)
{
size_t i;
for (i = 0; i < len; i++) {
if (data[i] < 32 || data[i] == 127)
return 1;
}
return 0;
}
size_t wpa_merge_byte_arrays(u8 *res, size_t res_len,
const u8 *src1, size_t src1_len,
const u8 *src2, size_t src2_len)
@@ -358,39 +439,36 @@ char * dup_binstr(const void *src, size_t len)
return res;
}
void wpa_bin_clear_free(void *bin, size_t len)
{
if (bin) {
os_memset(bin, 0, len);
os_free(bin);
}
}
int int_array_len(const int *a)
size_t int_array_len(const int *a)
{
int i;
size_t i;
for (i = 0; a && a[i]; i++)
;
return i;
}
void bin_clear_free(void *bin, size_t len)
{
if (bin) {
os_memset(bin, 0, len);
os_free(bin);
}
}
void str_clear_free(char *str)
{
if (str) {
size_t len = os_strlen(str);
os_memset(str, 0, len);
forced_memzero(str, len);
os_free(str);
}
}
void bin_clear_free(void *bin, size_t len)
{
if (bin) {
forced_memzero(bin, len);
os_free(bin);
}
}
int os_gmtime(os_time_t t, struct os_tm *tm)
{
struct tm *tm2;
@@ -430,6 +508,39 @@ int os_mktime(int year, int month, int day, int hour, int min, int sec,
return 0;
}
void * os_memdup(const void *src, size_t len)
{
void *r = os_malloc(len);
if (r && src)
os_memcpy(r, src, len);
return r;
}
int os_reltime_expired(struct os_time *now,
struct os_time *ts,
os_time_t timeout_secs)
{
struct os_time age;
os_time_sub(now, ts, &age);
return (age.sec > timeout_secs) ||
(age.sec == timeout_secs && age.usec > 0);
}
u8 rssi_to_rcpi(int rssi)
{
if (!rssi)
return 255; /* not available */
if (rssi < -110)
return 0;
if (rssi > 0)
return 220;
return (rssi + 110) * 2;
}
char * get_param(const char *cmd, const char *param)
{
const char *pos, *end;
@@ -453,102 +564,3 @@ char * get_param(const char *cmd, const char *param)
val[len] = '\0';
return val;
}
void * os_memdup(const void *src, size_t len)
{
void *r = os_malloc(len);
if (r && src)
os_memcpy(r, src, len);
return r;
}
/**
* hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
* @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
* Returns: Characters used (> 0) on success, -1 on failure
*/
int hwaddr_aton2(const char *txt, u8 *addr)
{
int i;
const char *pos = txt;
for (i = 0; i < 6; i++) {
int a, b;
while (*pos == ':' || *pos == '.' || *pos == '-')
pos++;
a = hex2num(*pos++);
if (a < 0)
return -1;
b = hex2num(*pos++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
}
return pos - txt;
}
static inline int os_reltime_expired(struct os_time *now,
struct os_time *ts,
os_time_t timeout_secs)
{
struct os_time age;
os_time_sub(now, ts, &age);
return (age.sec > timeout_secs) ||
(age.sec == timeout_secs && age.usec > 0);
}
int os_time_expired(struct os_time *now,
struct os_time *ts,
os_time_t timeout_secs)
{
return os_reltime_expired(now, ts, timeout_secs);
}
u8 rssi_to_rcpi(int rssi)
{
if (!rssi)
return 255; /* not available */
if (rssi < -110)
return 0;
if (rssi > 0)
return 220;
return (rssi + 110) * 2;
}
/**
* wpa_ssid_txt - Convert SSID to a printable string
* @ssid: SSID (32-octet string)
* @ssid_len: Length of ssid in octets
* Returns: Pointer to a printable string
*
* This function can be used to convert SSIDs into printable form. In most
* cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
* does not limit the used character set, so anything could be used in an SSID.
*
* This function uses a static buffer, so only one call can be used at the
* time, i.e., this is not re-entrant and the returned buffer must be used
* before calling this again.
*/
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
{
static char ssid_txt[SSID_MAX_LEN * 4 + 1];
if (ssid == NULL) {
ssid_txt[0] = '\0';
return ssid_txt;
}
printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
return ssid_txt;
}
void * __hide_aliasing_typecast(void *foo)
{
return foo;
}

View File

@@ -389,7 +389,7 @@ int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask);
u8 rssi_to_rcpi(int rssi);
int os_time_expired(struct os_time *now,
int os_reltime_expired(struct os_time *now,
struct os_time *ts,
os_time_t timeout_secs);
@@ -408,6 +408,7 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
char * wpa_config_parse_string(const char *value, size_t *len);
int wpa_is_hex(const u8 *data, size_t len);
int has_ctrl_char(const u8 *data, size_t len);
size_t wpa_merge_byte_arrays(u8 *res, size_t res_len,
const u8 *src1, size_t src1_len,
const u8 *src2, size_t src2_len);
@@ -447,8 +448,7 @@ struct wpa_freq_range_list {
#define TEST_FAIL() 0
#endif
void wpa_bin_clear_free(void *bin, size_t len);
int int_array_len(const int *a);
size_t int_array_len(const int *a);
void bin_clear_free(void *bin, size_t len);
void str_clear_free(char *str);
char * get_param(const char *cmd, const char *param);

View File

@@ -1,15 +1,9 @@
/*
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
* Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifdef ESP_SUPPLICANT
#include "utils/includes.h"

View File

@@ -5,20 +5,191 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include <string.h>
#include "utils/includes.h"
#include "rsn_supp/wpa.h"
#include "utils/common.h"
#include "common/eapol_common.h"
#include "utils/wpa_debug.h"
#include "includes.h"
#include "common.h"
#include "crypto/dh_group5.h"
#include "common/ieee802_11_defs.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
#include "wps/wps_i.h"
#include "wps/wps_dev_attr.h"
#include "eap_peer/eap_defs.h"
#include "eap_peer/eap_common.h"
#ifdef CONFIG_WPS_TESTING
int wps_version_number = 0x20;
int wps_testing_stub_cred = 0;
int wps_corrupt_pkhash = 0;
int wps_force_auth_types_in_use = 0;
u16 wps_force_auth_types = 0;
int wps_force_encr_types_in_use = 0;
u16 wps_force_encr_types = 0;
#endif /* CONFIG_WPS_TESTING */
/**
* wps_init - Initialize WPS Registration protocol data
* @cfg: WPS configuration
* Returns: Pointer to allocated data or %NULL on failure
*
* This function is used to initialize WPS data for a registration protocol
* instance (i.e., each run of registration protocol as a Registrar of
* Enrollee. The caller is responsible for freeing this data after the
* registration run has been completed by calling wps_deinit().
*/
struct wps_data * wps_init(const struct wps_config *cfg)
{
struct wps_data *data = os_zalloc(sizeof(*data));
if (data == NULL)
return NULL;
data->wps = cfg->wps;
data->registrar = cfg->registrar;
if (cfg->registrar) {
os_memcpy(data->uuid_r, cfg->wps->uuid, WPS_UUID_LEN);
} else {
os_memcpy(data->mac_addr_e, cfg->wps->dev.mac_addr, ETH_ALEN);
os_memcpy(data->uuid_e, cfg->wps->uuid, WPS_UUID_LEN);
}
if (cfg->pin) {
data->dev_pw_id = cfg->dev_pw_id;
data->dev_password = os_memdup(cfg->pin, cfg->pin_len);
if (data->dev_password == NULL) {
os_free(data);
return NULL;
}
data->dev_password_len = cfg->pin_len;
wpa_hexdump_key(MSG_DEBUG, "WPS: AP PIN dev_password",
data->dev_password, data->dev_password_len);
}
#ifdef CONFIG_WPS_NFC
if (cfg->pin == NULL &&
cfg->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)
data->dev_pw_id = cfg->dev_pw_id;
if (cfg->wps->ap && !cfg->registrar && cfg->wps->ap_nfc_dev_pw_id) {
/* Keep AP PIN as alternative Device Password */
data->alt_dev_pw_id = data->dev_pw_id;
data->alt_dev_password = data->dev_password;
data->alt_dev_password_len = data->dev_password_len;
data->dev_pw_id = cfg->wps->ap_nfc_dev_pw_id;
data->dev_password =
os_memdup(wpabuf_head(cfg->wps->ap_nfc_dev_pw),
wpabuf_len(cfg->wps->ap_nfc_dev_pw));
if (data->dev_password == NULL) {
os_free(data);
return NULL;
}
data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw);
wpa_hexdump_key(MSG_DEBUG, "WPS: NFC dev_password",
data->dev_password, data->dev_password_len);
}
#endif /* CONFIG_WPS_NFC */
data->pbc = cfg->pbc;
if (cfg->pbc) {
/* Use special PIN '00000000' for PBC */
data->dev_pw_id = DEV_PW_PUSHBUTTON;
bin_clear_free(data->dev_password, data->dev_password_len);
data->dev_password = (u8 *) os_strdup("00000000");
if (data->dev_password == NULL) {
os_free(data);
return NULL;
}
data->dev_password_len = 8;
}
data->state = data->registrar ? RECV_M1 : SEND_M1;
#ifndef ESP_SUPPLICANT
if (cfg->assoc_wps_ie) {
struct wps_parse_attr attr;
wpa_hexdump_buf(MSG_DEBUG, "WPS: WPS IE from (Re)AssocReq",
cfg->assoc_wps_ie);
if (wps_parse_msg(cfg->assoc_wps_ie, &attr) < 0) {
wpa_printf(MSG_DEBUG, "WPS: Failed to parse WPS IE "
"from (Re)AssocReq");
} else if (attr.request_type == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No Request Type attribute "
"in (Re)AssocReq WPS IE");
} else {
wpa_printf(MSG_DEBUG, "WPS: Request Type (from WPS IE "
"in (Re)AssocReq WPS IE): %d",
*attr.request_type);
data->request_type = *attr.request_type;
}
}
if (cfg->new_ap_settings) {
data->new_ap_settings =
os_memdup(cfg->new_ap_settings,
sizeof(*data->new_ap_settings));
if (data->new_ap_settings == NULL) {
bin_clear_free(data->dev_password,
data->dev_password_len);
os_free(data);
return NULL;
}
}
if (cfg->peer_addr)
os_memcpy(data->peer_dev.mac_addr, cfg->peer_addr, ETH_ALEN);
if (cfg->p2p_dev_addr)
os_memcpy(data->p2p_dev_addr, cfg->p2p_dev_addr, ETH_ALEN);
data->use_psk_key = cfg->use_psk_key;
data->pbc_in_m1 = cfg->pbc_in_m1;
if (cfg->peer_pubkey_hash) {
os_memcpy(data->peer_pubkey_hash, cfg->peer_pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN);
data->peer_pubkey_hash_set = 1;
}
data->multi_ap_backhaul_sta = cfg->multi_ap_backhaul_sta;
#endif
return data;
}
/**
* wps_deinit - Deinitialize WPS Registration protocol data
* @data: WPS Registration protocol data from wps_init()
*/
void wps_deinit(struct wps_data *data)
{
#ifdef CONFIG_WPS_NFC
if (data->registrar && data->nfc_pw_token)
wps_registrar_remove_nfc_pw_token(data->wps->registrar,
data->nfc_pw_token);
#endif /* CONFIG_WPS_NFC */
#ifdef CONFIG_WPS_REGISTRAR
if (data->wps_pin_revealed) {
wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
"negotiation failed");
if (data->registrar)
wps_registrar_invalidate_pin(data->wps->registrar,
data->uuid_e);
} else if (data->registrar)
wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e);
#endif
wpabuf_clear_free(data->dh_privkey);
wpabuf_free(data->dh_pubkey_e);
wpabuf_free(data->dh_pubkey_r);
wpabuf_free(data->last_msg);
bin_clear_free(data->dev_password, data->dev_password_len);
#ifndef ESP_SUPPLICANT
bin_clear_free(data->alt_dev_password, data->alt_dev_password_len);
bin_clear_free(data->new_psk, data->new_psk_len);
#endif /* ESP_SUPPLICANT */
wps_device_data_free(&data->peer_dev);
bin_clear_free(data->new_ap_settings, sizeof(*data->new_ap_settings));
dh5_free(data->dh_ctx);
os_free(data);
}
/**
@@ -69,7 +240,7 @@ struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code)
*/
int wps_is_selected_pbc_registrar(const struct wpabuf *msg)
{
struct wps_parse_attr *attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
struct wps_parse_attr *attr = os_zalloc(sizeof(struct wps_parse_attr));
if (!attr)
return 0;
@@ -103,7 +274,6 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg)
return 1;
}
#ifdef CONFIG_WPS_PIN
static int is_selected_pin_registrar(struct wps_parse_attr *attr)
{
@@ -143,7 +313,7 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg)
struct wps_parse_attr *attr;
int ret;
attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
attr = os_zalloc(sizeof(struct wps_parse_attr));
if (attr == NULL)
return -99;
@@ -157,7 +327,6 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg)
return ret;
}
#endif
/**
* wps_is_addr_authorized - Check whether WPS IE authorizes MAC address
@@ -176,7 +345,7 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
const u8 *pos;
const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
attr = os_zalloc(sizeof(struct wps_parse_attr));
if (attr == NULL) {
ret = 0;
goto _out;
@@ -192,11 +361,9 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
* Version 1.0 AP - AuthorizedMACs not used, so revert back to
* old mechanism of using SelectedRegistrar.
*/
#ifdef CONFIG_WPS_PIN
ret = is_selected_pin_registrar(attr);
goto _out;
#endif
}
if (!attr->authorized_macs) {
@@ -343,7 +510,7 @@ struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type)
if (wps_build_version(ie) ||
wps_build_req_type(ie, req_type) ||
wps_build_wfa_ext(ie, 0, NULL, 0)) {
wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
wpabuf_free(ie);
return NULL;
}
@@ -377,7 +544,7 @@ struct wpabuf * wps_build_assoc_resp_ie(void)
if (wps_build_version(ie) ||
wps_build_resp_type(ie, WPS_RESP_AP) ||
wps_build_wfa_ext(ie, 0, NULL, 0)) {
wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
wpabuf_free(ie);
return NULL;
}
@@ -410,30 +577,26 @@ struct wpabuf * wps_build_probe_req_ie(u16 pw_id, struct wps_device_data *dev,
{
struct wpabuf *ie;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request\n");
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
ie = wpabuf_alloc(400);
if (ie == NULL) {
wpa_printf(MSG_ERROR, "WPS: ie alloc failed.");
ie = wpabuf_alloc(500);
if (ie == NULL)
return NULL;
}
if (wps_build_version(ie) ||
wps_build_req_type(ie, req_type) ||
wps_build_config_methods(ie, dev->config_methods) ||
wps_build_uuid_e(ie, uuid) ||
wps_build_primary_dev_type(dev, ie) ||
wps_build_rf_bands(dev, ie) ||
wps_build_rf_bands(dev, ie, 0) ||
wps_build_assoc_state(NULL, ie) ||
wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
wps_build_dev_password_id(ie, pw_id) ||
#ifdef CONFIG_WPS2
wps_build_manufacturer(dev, ie) ||
wps_build_model_name(dev, ie) ||
wps_build_model_number(dev, ie) ||
wps_build_dev_name(dev, ie) ||
wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
#endif /* CONFIG_WPS2 */
wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
||
wps_build_secondary_dev_type(dev, ie)
@@ -442,13 +605,6 @@ struct wpabuf * wps_build_probe_req_ie(u16 pw_id, struct wps_device_data *dev,
return NULL;
}
#ifndef CONFIG_WPS2
if (dev->p2p && wps_build_dev_name(dev, ie)) {
wpabuf_free(ie);
return NULL;
}
#endif /* CONFIG_WPS2 */
return wps_ie_encapsulate(ie);
}

View File

@@ -1,6 +1,6 @@
/*
* Wi-Fi Protected Setup
* Copyright (c) 2007-2012, 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.
* See README for more details.
@@ -9,13 +9,8 @@
#ifndef WPS_H
#define WPS_H
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h" // will be removed in idf v5.0
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#endif
#include "common/ieee802_11_defs.h"
#include "wps_defs.h"
#include "esp_wifi_types.h"
/**
* enum wsc_op_code - EAP-WSC OP-Code values
@@ -31,6 +26,7 @@ enum wsc_op_code {
};
struct wps_registrar;
struct upnp_wps_device_sm;
struct wps_er;
struct wps_parse_attr;
@@ -38,7 +34,7 @@ struct wps_parse_attr;
* struct wps_credential - WPS Credential
* @ssid: SSID
* @ssid_len: Length of SSID
* @auth_type: Authentication Type (WPS_WIFI_AUTH_OPEN, .. flags)
* @auth_type: Authentication Type (WPS_AUTH_OPEN, .. flags)
* @encr_type: Encryption Type (WPS_ENCR_NONE, .. flags)
* @key_idx: Key index
* @key: Key
@@ -47,10 +43,9 @@ struct wps_parse_attr;
* @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
* this may be %NULL, if not used
* @cred_attr_len: Length of cred_attr in octets
* @ap_channel: AP channel
*/
struct wps_credential {
u8 ssid[32];
u8 ssid[SSID_MAX_LEN];
size_t ssid_len;
u16 auth_type;
u16 encr_type;
@@ -60,7 +55,6 @@ struct wps_credential {
u8 mac_addr[ETH_ALEN];
const u8 *cred_attr;
size_t cred_attr_len;
u16 ap_channel;
};
#define WPS_DEV_TYPE_LEN 8
@@ -85,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 {
@@ -104,8 +98,10 @@ struct wps_device_data {
u16 config_methods;
struct wpabuf *vendor_ext_m1;
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
struct wpabuf *application_ext;
int p2p;
u8 multi_ap_ext;
};
/**
@@ -136,7 +132,7 @@ struct wps_config {
* pbc - Whether this is protocol run uses PBC
*/
int pbc;
#ifndef ESP_SUPPLICANT
/**
* assoc_wps_ie: (Re)AssocReq WPS IE (in AP; %NULL if not AP)
*/
@@ -166,11 +162,13 @@ struct wps_config {
*/
int use_psk_key;
#endif
/**
* dev_pw_id - Device Password ID for Enrollee when PIN is used
*/
u16 dev_pw_id;
#ifndef ESP_SUPPLICANT
/**
* p2p_dev_addr - P2P Device Address from (Re)Association Request
*
@@ -188,16 +186,23 @@ struct wps_config {
* PBC with the AP.
*/
int pbc_in_m1;
/**
* peer_pubkey_hash - Peer public key hash or %NULL if not known
*/
const u8 *peer_pubkey_hash;
/**
* multi_ap_backhaul_sta - Whether this is a Multi-AP backhaul STA
* enrollee
*/
int multi_ap_backhaul_sta;
#endif
};
/* Bssid of the discard AP which is discarded for not select reg or other reason */
struct discard_ap_list_t{
u8 bssid[6];
};
struct wps_data * wps_init(const struct wps_config *cfg);
struct wps_data * wps_init(void);
void wps_deinit(void);
void wps_deinit(struct wps_data *data);
/**
* enum wps_process_res - WPS message processing result
@@ -259,14 +264,15 @@ struct wps_registrar_config {
* new_psk_cb - Callback for new PSK
* @ctx: Higher layer context data (cb_ctx)
* @mac_addr: MAC address of the Enrollee
* @p2p_dev_addr: P2P Device Address of the Enrollee or all zeros if not
* @psk: The new PSK
* @psk_len: The length of psk in octets
* Returns: 0 on success, -1 on failure
*
* This callback is called when a new per-device PSK is provisioned.
*/
int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
size_t psk_len);
int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
const u8 *psk, size_t psk_len);
/**
* set_ie_cb - Callback for WPS IE changes
@@ -344,6 +350,14 @@ struct wps_registrar_config {
u16 dev_password_id, u8 request_type,
const char *dev_name);
/**
* lookup_pskfile_cb - Callback for searching for PSK in wpa_psk_file
* @ctx: Higher layer context data (cb_ctx)
* @addr: Enrollee's MAC address
* @psk: Pointer to found PSK (output arg)
*/
int (*lookup_pskfile_cb)(void *ctx, const u8 *mac_addr, const u8 **psk);
/**
* cb_ctx: Higher layer context data for Registrar callbacks
*/
@@ -386,15 +400,49 @@ struct wps_registrar_config {
*/
int disable_auto_conf;
/**
* static_wep_only - Whether the BSS supports only static WEP
*/
int static_wep_only;
/**
* dualband - Whether this is a concurrent dualband AP
*/
int dualband;
/**
* force_per_enrollee_psk - Force per-Enrollee random PSK
*
* This forces per-Enrollee random PSK to be generated even if a default
* 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;
};
@@ -432,6 +480,16 @@ enum wps_event {
*/
WPS_EV_PBC_TIMEOUT,
/**
* WPS_EV_PBC_ACTIVE - PBC mode was activated
*/
WPS_EV_PBC_ACTIVE,
/**
* WPS_EV_PBC_DISABLE - PBC mode was disabled
*/
WPS_EV_PBC_DISABLE,
/**
* WPS_EV_ER_AP_ADD - ER: AP added
*/
@@ -500,11 +558,17 @@ union wps_event_data {
int msg;
u16 config_error;
u16 error_indication;
u8 peer_macaddr[ETH_ALEN];
} fail;
struct wps_event_success {
u8 peer_macaddr[ETH_ALEN];
} success;
struct wps_event_pwd_auth_fail {
int enrollee;
int part;
u8 peer_macaddr[ETH_ALEN];
} pwd_auth_fail;
struct wps_event_er_ap {
@@ -568,7 +632,6 @@ struct upnp_pending_message {
struct wpabuf *msg;
enum wps_msg_type type;
};
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
#endif
/**
* struct wps_context - Long term WPS context data
@@ -609,7 +672,7 @@ struct wps_context {
* Credentials. In addition, AP uses it when acting as an Enrollee to
* notify Registrar of the current configuration.
*/
u8 ssid[32];
u8 ssid[SSID_MAX_LEN];
/**
* ssid_len - Length of ssid in octets
@@ -648,11 +711,31 @@ struct wps_context {
*/
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_*)
*/
u16 auth_types;
/**
* encr_types - Current AP encryption type (WPS_ENCR_*)
*/
u16 ap_encr_type;
/**
* ap_auth_type - Current AP authentication types (WPS_AUTH_*)
*/
u16 ap_auth_type;
/**
* network_key - The current Network Key (PSK) or %NULL to generate new
*
@@ -660,7 +743,7 @@ struct wps_context {
* uses this when acting as an Enrollee to notify Registrar of the
* current configuration.
*
* When using WPA/WPA2-Person, this key can be either the ASCII
* When using WPA/WPA2-Personal, 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
@@ -743,35 +826,43 @@ struct wps_context {
void (*event_cb)(void *ctx, enum wps_event event,
union wps_event_data *data);
/**
* rf_band_cb - Fetch currently used RF band
* @ctx: Higher layer context data (cb_ctx)
* Return: Current used RF band or 0 if not known
*/
int (*rf_band_cb)(void *ctx);
/**
* cb_ctx: Higher layer context data for callbacks
*/
void *cb_ctx;
struct upnp_wps_device_sm *wps_upnp;
/* Pending messages from UPnP PutWLANResponse */
#ifdef CONFIG_WPS_NFC
struct upnp_pending_message *upnp_msgs;
u16 ap_nfc_dev_pw_id;
struct wpabuf *ap_nfc_dh_pubkey;
struct wpabuf *ap_nfc_dh_privkey;
struct wpabuf *ap_nfc_dev_pw;
#endif
/* Whether to send WPA2-PSK passphrase as a passphrase instead of PSK
* for WPA3-Personal transition mode needs. */
bool use_passphrase;
};
struct wps_registrar *
wps_registrar_init(struct wps_context *wps,
const struct wps_registrar_config *cfg);
void wps_registrar_deinit(struct wps_registrar *reg);
#ifdef CONFIG_WPS_PIN
int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
const u8 *uuid, const u8 *pin, size_t pin_len,
int timeout);
int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid);
int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid);
#endif
int wps_registrar_wps_cancel(struct wps_registrar *reg);
int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid);
int wps_registrar_button_pushed(struct wps_registrar *reg,
const u8 *p2p_dev_addr);
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
@@ -788,27 +879,35 @@ int wps_registrar_config_ap(struct wps_registrar *reg,
int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
const u8 *pubkey_hash, u16 pw_id,
const u8 *dev_pw, size_t dev_pw_len);
const u8 *dev_pw, size_t dev_pw_len,
int pk_hash_provided_oob);
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
const u8 *oob_dev_pw,
size_t oob_dev_pw_len);
#endif
void wps_registrar_flush(struct wps_registrar *reg);
int wps_registrar_update_multi_ap(struct wps_registrar *reg,
const u8 *multi_ap_backhaul_ssid,
size_t multi_ap_backhaul_ssid_len,
const u8 *multi_ap_backhaul_network_key,
size_t multi_ap_backhaul_network_key_len);
int wps_build_credential_wrap(struct wpabuf *msg,
const struct wps_credential *cred);
#ifdef CONFIG_WPS_PIN
unsigned int wps_pin_checksum(unsigned int pin);
unsigned int wps_pin_valid(unsigned int pin);
int wps_generate_pin(unsigned int *pin);
int wps_pin_str_valid(const char *pin);
#endif
unsigned int wps_generate_pin(void);
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
#ifdef CONFIG_WPS_OOB
struct wpabuf * wps_get_oob_cred(struct wps_context *wps);
struct wpabuf * wps_get_oob_cred(struct wps_context *wps, int rf_band,
int channel);
int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr);
#endif
int wps_attr_text(struct wpabuf *data, char *buf, char *end);
const char * wps_ei_str(enum wps_error_indication ei);
struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname,
const char *filter);
@@ -816,18 +915,22 @@ void wps_er_refresh(struct wps_er *er);
void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx);
void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
u16 sel_reg_config_methods);
int wps_er_pbc(struct wps_er *er, const u8 *uuid);
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
size_t pin_len);
int wps_er_set_config(struct wps_er *er, const u8 *uuid,
int wps_er_pbc(struct wps_er *er, const u8 *uuid, const u8 *addr);
const u8 * wps_er_get_sta_uuid(struct wps_er *er, const u8 *addr);
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
const u8 *pin, size_t pin_len);
int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
const struct wps_credential *cred);
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
size_t pin_len, const struct wps_credential *cred);
#ifdef CONFIG_WPS_NFC
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid);
#endif
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
const u8 *pin, size_t pin_len,
const struct wps_credential *cred);
struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
struct wps_credential *cred);
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
const u8 *addr);
struct wpabuf * wps_er_nfc_handover_sel(struct wps_er *er,
struct wps_context *wps, const u8 *uuid,
const u8 *addr, struct wpabuf *pubkey);
int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]);
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
@@ -840,15 +943,30 @@ u16 wps_config_methods_str2bin(const char *str);
struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id,
const struct wpabuf *pubkey,
const struct wpabuf *dev_pw);
struct wpabuf * wps_nfc_token_build(int ndef, int id, struct wpabuf *pubkey,
struct wpabuf *dev_pw);
int wps_nfc_gen_dh(struct wpabuf **pubkey, struct wpabuf **privkey);
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
struct wpabuf **privkey,
struct wpabuf **dev_pw);
struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey);
struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey,
const u8 *bssid, int freq);
struct wpabuf * wps_build_nfc_handover_req_p2p(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey);
struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx,
int nfc_dev_pw_id,
struct wpabuf *nfc_dh_pubkey,
struct wpabuf *nfc_dev_pw);
#endif
/* ndef.c */
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
struct wpabuf * ndef_build_wifi(const struct wpabuf *buf);
struct wpabuf * ndef_build_wifi_hr(void);
struct wpabuf * ndef_parse_p2p(const struct wpabuf *buf);
struct wpabuf * ndef_build_p2p(const struct wpabuf *buf);
#ifdef CONFIG_WPS_STRICT
int wps_validate_beacon(const struct wpabuf *wps_ie);
@@ -996,79 +1114,4 @@ static inline int wps_validate_upnp_set_selected_registrar(
}
#endif /* CONFIG_WPS_STRICT */
enum wps_cb_status {
WPS_CB_ST_SUCCESS = 0,
WPS_CB_ST_FAILED,
WPS_CB_ST_TIMEOUT,
WPS_CB_ST_WEP,
WPS_CB_ST_SCAN_ERR,
};
typedef void (*wps_st_cb_t)(int status);
#ifdef USE_WPS_TASK
enum wps_sig_type {
SIG_WPS_ENABLE = 1, //1
SIG_WPS_DISABLE, //2
SIG_WPS_START, //3
SIG_WPS_RX, //4
SIG_WPS_TIMER_TIMEOUT, //5
SIG_WPS_TIMER_MSG_TIMEOUT, //6
SIG_WPS_TIMER_SUCCESS_CB, //7
SIG_WPS_TIMER_SCAN, //8
SIG_WPS_TIMER_EAPOL_START, //9
SIG_WPS_NUM, //10
};
#endif
#define WPS_EAP_EXT_VENDOR_TYPE "WFA-SimpleConfig-Enrollee-1-0"
#define WPS_OUTBUF_SIZE 500
struct wps_sm {
struct wps_config *wps_cfg;
struct wps_context *wps_ctx;
struct wps_data *wps;
char identity[32];
u8 identity_len;
u8 ownaddr[ETH_ALEN];
u8 bssid[ETH_ALEN];
u8 ssid[MAX_WPS_AP_CRED][MAX_SSID_LEN];
u8 ssid_len[MAX_WPS_AP_CRED];
char key[MAX_WPS_AP_CRED][MAX_PASSPHRASE_LEN];
u8 key_len[MAX_WPS_AP_CRED];
u8 ap_cred_cnt;
struct wps_device_data *dev;
u8 uuid[16];
u8 eapol_version;
ETSTimer wps_timeout_timer;
ETSTimer wps_msg_timeout_timer;
ETSTimer wps_scan_timer;
ETSTimer wps_success_cb_timer;
ETSTimer wps_eapol_start_timer;
wps_st_cb_t st_cb;
u8 current_identifier;
bool is_wps_scan;
u8 channel;
u8 scan_cnt;
#ifdef USE_WPS_TASK
u8 wps_sig_cnt[SIG_WPS_NUM];
#endif
u8 discover_ssid_cnt;
bool ignore_sel_reg;
bool wps_pin_war;
struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM];
u8 discard_ap_cnt;
wifi_sta_config_t config;
};
#define WIFI_CAPINFO_PRIVACY 0x0010
struct wps_sm *wps_sm_get(void);
int wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx);
int wps_key_save(char *key, u8 key_len, u8 idx);
int wps_station_wps_register_cb(wps_st_cb_t cb);
int wps_station_wps_unregister_cb(void);
int wps_start_pending(void);
int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
int wps_dev_deinit(struct wps_device_data *dev);
#endif /* WPS_H */

View File

@@ -1,56 +1,72 @@
/*
* Wi-Fi Protected Setup - attribute building
* Copyright (c) 2008, 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.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "utils/wpa_debug.h"
#include "includes.h"
#include "common.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
#include "crypto/dh_group5.h"
#include "crypto/sha256.h"
#include "crypto/random.h"
#include "crypto/dh_group5.h"
#include "common/ieee802_11_defs.h"
#include "wps/wps_i.h"
#include "wps_i.h"
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_t mode)
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
{
struct wpabuf *pubkey = NULL;
if (mode != WPS_CALC_KEY_NO_CALC) {
wpa_printf(MSG_DEBUG, "WPS: * Public Key");
wpabuf_free(wps->dh_privkey);
if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) {
wpabuf_clear_free(wps->dh_privkey);
wps->dh_privkey = NULL;
if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey &&
wps->wps->dh_ctx) {
wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
if (wps->wps->dh_pubkey == NULL) {
wpa_printf(MSG_DEBUG,
"WPS: wps->wps->dh_pubkey == NULL");
return -1;
}
wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
wps->dh_ctx = wps->wps->dh_ctx;
wps->wps->dh_ctx = NULL;
pubkey = wpabuf_dup(wps->wps->dh_pubkey);
#ifdef CONFIG_WPS_NFC
} else if (wps->dev_pw_id >= 0x10 && wps->wps->ap &&
wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id) {
} else if ((wps->dev_pw_id >= 0x10 ||
wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) &&
(wps->wps->ap ||
(wps->wps->ap_nfc_dh_pubkey &&
wps->wps->ap_nfc_dev_pw_id ==
DEV_PW_NFC_CONNECTION_HANDOVER &&
wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)) &&
(wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id ||
wps->wps->ap_nfc_dh_pubkey)) {
wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys");
if (wps->wps->ap_nfc_dh_privkey == NULL) {
wpa_printf(MSG_DEBUG,
"WPS: wps->wps->ap_nfc_dh_privkey == NULL");
return -1;
}
if (wps->wps->ap_nfc_dh_pubkey == NULL) {
wpa_printf(MSG_DEBUG,
"WPS: wps->wps->ap_nfc_dh_pubkey == NULL");
return -1;
}
wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey);
pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey);
if (wps->dh_privkey && pubkey)
wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey);
#endif /* CONFIG_WPS_NFC */
} else {
wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
wps->dh_privkey = NULL;
dh5_free(wps->dh_ctx);
wpa_printf(MSG_DEBUG, "build public key start\n");
wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
wpa_printf(MSG_DEBUG, "build public key finish\n");
pubkey = wpabuf_zeropad(pubkey, 192);
}
if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) {
@@ -62,6 +78,16 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_
wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey);
#ifdef ESP_SUPPLICANT
if (msg) {
#endif
wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
wpabuf_put_be16(msg, wpabuf_len(pubkey));
wpabuf_put_buf(msg, pubkey);
#ifdef ESP_SUPPLICANT
}
#endif
if (wps->registrar) {
wpabuf_free(wps->dh_pubkey_r);
wps->dh_pubkey_r = pubkey;
@@ -70,19 +96,6 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_
wps->dh_pubkey_e = pubkey;
}
}
if (mode != WPS_CALC_KEY_PRE_CALC) {
if (wps->registrar)
pubkey = wps->dh_pubkey_r;
else
pubkey = wps->dh_pubkey_e;
wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
wpabuf_put_be16(msg, wpabuf_len(pubkey));
wpabuf_put_buf(msg, pubkey);
}
return 0;
}
@@ -119,6 +132,8 @@ int wps_build_config_methods(struct wpabuf *msg, u16 methods)
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
{
if (wpabuf_tailroom(msg) < 4 + WPS_UUID_LEN)
return -1;
wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
wpabuf_put_be16(msg, ATTR_UUID_E);
wpabuf_put_be16(msg, WPS_UUID_LEN);
@@ -166,7 +181,10 @@ int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
len[0] = wpabuf_len(wps->last_msg);
addr[1] = wpabuf_head(msg);
len[1] = wpabuf_len(msg);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
if (hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len,
hash) < 0)
return -1;
wpa_printf(MSG_DEBUG, "WPS: * Authenticator");
wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
@@ -183,6 +201,8 @@ int wps_build_version(struct wpabuf *msg)
* backwards compatibility reasons. The real version negotiation is
* done with Version2.
*/
if (wpabuf_tailroom(msg) < 5)
return -1;
wpa_printf(MSG_DEBUG, "WPS: * Version (hardcoded 0x10)");
wpabuf_put_be16(msg, ATTR_VERSION);
wpabuf_put_be16(msg, 1);
@@ -192,11 +212,20 @@ int wps_build_version(struct wpabuf *msg)
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
const u8 *auth_macs, size_t auth_macs_count)
const u8 *auth_macs, size_t auth_macs_count,
u8 multi_ap_subelem)
{
#ifdef CONFIG_WPS2
u8 *len;
#ifdef CONFIG_WPS_TESTING
if (WPS_VERSION == 0x10)
return 0;
#endif /* CONFIG_WPS_TESTING */
if (wpabuf_tailroom(msg) <
7 + 3 + (req_to_enroll ? 3 : 0) +
(auth_macs ? 2 + auth_macs_count * ETH_ALEN : 0))
return -1;
wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
len = wpabuf_put(msg, 2); /* to be filled */
wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
@@ -225,11 +254,20 @@ int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
MAC2STR(&auth_macs[i * ETH_ALEN]));
}
if (multi_ap_subelem) {
wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)",
multi_ap_subelem);
wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP);
wpabuf_put_u8(msg, 1); /* length */
wpabuf_put_u8(msg, multi_ap_subelem);
}
WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
#endif /* CONFIG_WPS2 */
#ifdef CONFIG_WPS_TESTING
if (WPS_VERSION > 0x20) {
if (wpabuf_tailroom(msg) < 5)
return -1;
wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra "
"attribute");
wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST);
@@ -274,10 +312,23 @@ int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
{
u16 auth_types = WPS_AUTH_TYPES;
#ifdef CONFIG_WPS2
/* WPA/WPA2-Enterprise enrollment not supported through WPS */
auth_types &= ~WPS_AUTH_WPA;
auth_types &= ~WPS_AUTH_WPA2;
auth_types &= ~WPS_AUTH_SHARED;
#endif /* CONFIG_WPS2 */
wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags");
#ifdef CONFIG_NO_TKIP
auth_types &= ~WPS_AUTH_WPAPSK;
#endif /* CONFIG_NO_TKIP */
#ifdef CONFIG_WPS_TESTING
if (wps_force_auth_types_in_use) {
wpa_printf(MSG_DEBUG,
"WPS: Testing - replace auth type 0x%x with 0x%x",
auth_types, wps_force_auth_types);
auth_types = wps_force_auth_types;
}
#endif /* CONFIG_WPS_TESTING */
wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags (0x%x)",
auth_types);
wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, auth_types);
@@ -288,10 +339,20 @@ int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
{
u16 encr_types = WPS_ENCR_TYPES;
#ifdef CONFIG_WPS2
encr_types &= ~WPS_ENCR_WEP;
#endif /* CONFIG_WPS2 */
wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags");
#ifdef CONFIG_NO_TKIP
encr_types &= ~WPS_ENCR_TKIP;
#endif /* CONFIG_NO_TKIP */
#ifdef CONFIG_WPS_TESTING
if (wps_force_encr_types_in_use) {
wpa_printf(MSG_DEBUG,
"WPS: Testing - replace encr type 0x%x with 0x%x",
encr_types, wps_force_encr_types);
encr_types = wps_force_encr_types;
}
#endif /* CONFIG_WPS_TESTING */
wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags (0x%x)",
encr_types);
wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, encr_types);
@@ -324,8 +385,10 @@ int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
u8 hash[SHA256_MAC_LEN];
wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator");
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
wpabuf_len(msg), hash);
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
wpabuf_len(msg), hash) < 0)
return -1;
wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
wpabuf_put_be16(msg, WPS_KWA_LEN);
wpabuf_put_data(msg, hash, WPS_KWA_LEN);
@@ -355,9 +418,9 @@ int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
data = wpabuf_put(msg, 0);
wpabuf_put_buf(msg, plain);
wpa_printf(MSG_DEBUG, "WPS: * AES 128 Encrypted Settings");
if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
return -1;
return 0;
}
@@ -371,14 +434,32 @@ int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id,
const u8 *addr[1];
u8 pubkey_hash[WPS_HASH_LEN];
wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password (dev_pw_id=%u)",
dev_pw_id);
addr[0] = wpabuf_head(pubkey);
hash_len = wpabuf_len(pubkey);
sha256_vector(1, addr, &hash_len, pubkey_hash);
if (sha256_vector(1, addr, &hash_len, pubkey_hash) < 0)
return -1;
#ifdef CONFIG_WPS_TESTING
if (wps_corrupt_pkhash) {
wpa_hexdump(MSG_DEBUG, "WPS: Real Public Key Hash",
pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
wpa_printf(MSG_INFO, "WPS: Testing - corrupt public key hash");
pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN - 2]++;
}
#endif /* CONFIG_WPS_TESTING */
wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD);
wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len);
wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash",
pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
wpabuf_put_be16(msg, dev_pw_id);
if (dev_pw) {
wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password",
dev_pw, dev_pw_len);
wpabuf_put_data(msg, dev_pw, dev_pw_len);
}
return 0;
}
@@ -415,3 +496,34 @@ struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
return ie;
}
int wps_build_mac_addr(struct wpabuf *msg, const u8 *addr)
{
wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")",
MAC2STR(addr));
wpabuf_put_be16(msg, ATTR_MAC_ADDR);
wpabuf_put_be16(msg, ETH_ALEN);
wpabuf_put_data(msg, addr, ETH_ALEN);
return 0;
}
int wps_build_rf_bands_attr(struct wpabuf *msg, u8 rf_bands)
{
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", rf_bands);
wpabuf_put_be16(msg, ATTR_RF_BANDS);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, rf_bands);
return 0;
}
int wps_build_ap_channel(struct wpabuf *msg, u16 ap_channel)
{
wpa_printf(MSG_DEBUG, "WPS: * AP Channel (%u)", ap_channel);
wpabuf_put_be16(msg, ATTR_AP_CHANNEL);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, ap_channel);
return 0;
}

View File

@@ -5,11 +5,12 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "wps/wps_defs.h"
#include "wps/wps_attr_parse.h"
#include "includes.h"
#include "common.h"
#include "wps_defs.h"
#include "wps_attr_parse.h"
#ifndef CONFIG_WPS_STRICT
#define WPS_WORKAROUNDS
@@ -19,7 +20,7 @@
static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
u8 id, u8 len, const u8 *pos)
{
wpa_printf(MSG_MSGDUMP, "WPS: WFA subelement id=%u len=%u",
wpa_printf(MSG_EXCESSIVE, "WPS: WFA subelement id=%u len=%u",
id, len);
switch (id) {
case WFA_ELEM_VERSION2:
@@ -58,8 +59,27 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
}
attr->settings_delay_time = pos;
break;
case WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS:
if (len != 2) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Configuration Methods length %u",
len);
return -1;
}
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_DEBUG, "WPS: Skipped unknown WFA Vendor "
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
"Extension subelement %u", id);
break;
}
@@ -74,10 +94,10 @@ static int wps_parse_vendor_ext_wfa(struct wps_parse_attr *attr, const u8 *pos,
const u8 *end = pos + len;
u8 id, elen;
while (pos + 2 < end) {
while (end - pos >= 2) {
id = *pos++;
elen = *pos++;
if (pos + elen > end)
if (elen > end - pos)
break;
if (wps_set_vendor_ext_wfa_subelem(attr, id, elen, pos) < 0)
return -1;
@@ -106,7 +126,7 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
/* Handle unknown vendor extensions */
wpa_printf(MSG_DEBUG, "WPS: Unknown Vendor Extension (Vendor ID %u)",
wpa_printf(MSG_MSGDUMP, "WPS: Unknown Vendor Extension (Vendor ID %u)",
vendor_id);
if (len > WPS_MAX_VENDOR_EXT_LEN) {
@@ -128,6 +148,7 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
return 0;
}
static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
const u8 *pos, u16 len)
{
@@ -261,10 +282,13 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->dev_password_id = pos;
break;
case ATTR_OOB_DEVICE_PASSWORD:
if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
WPS_OOB_DEVICE_PASSWORD_LEN) {
WPS_OOB_DEVICE_PASSWORD_LEN ||
(len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
WPS_OOB_DEVICE_PASSWORD_MIN_LEN &&
WPA_GET_BE16(pos + WPS_OOB_PUBKEY_HASH_LEN) !=
DEV_PW_NFC_CONNECTION_HANDOVER)) {
wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
"Password length %u", len);
return -1;
@@ -408,22 +432,6 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
}
attr->mac_addr = pos;
break;
case ATTR_KEY_PROVIDED_AUTO:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
"Automatically length %u", len);
return -1;
}
attr->key_prov_auto = pos;
break;
case ATTR_802_1X_ENABLED:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
"length %u", len);
return -1;
}
attr->dot1x_enabled = pos;
break;
case ATTR_SELECTED_REGISTRAR:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
@@ -450,25 +458,55 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
break;
case ATTR_MANUFACTURER:
attr->manufacturer = pos;
if (len > WPS_MANUFACTURER_MAX_LEN)
attr->manufacturer_len = WPS_MANUFACTURER_MAX_LEN;
else
attr->manufacturer_len = len;
break;
case ATTR_MODEL_NAME:
attr->model_name = pos;
if (len > WPS_MODEL_NAME_MAX_LEN)
attr->model_name_len = WPS_MODEL_NAME_MAX_LEN;
else
attr->model_name_len = len;
break;
case ATTR_MODEL_NUMBER:
attr->model_number = pos;
if (len > WPS_MODEL_NUMBER_MAX_LEN)
attr->model_number_len = WPS_MODEL_NUMBER_MAX_LEN;
else
attr->model_number_len = len;
break;
case ATTR_SERIAL_NUMBER:
attr->serial_number = pos;
if (len > WPS_SERIAL_NUMBER_MAX_LEN)
attr->serial_number_len = WPS_SERIAL_NUMBER_MAX_LEN;
else
attr->serial_number_len = len;
break;
case ATTR_DEV_NAME:
if (len > WPS_DEV_NAME_MAX_LEN) {
wpa_printf(MSG_DEBUG,
"WPS: Ignore too long Device Name (len=%u)",
len);
break;
}
attr->dev_name = pos;
attr->dev_name_len = len;
break;
case ATTR_PUBLIC_KEY:
/*
* The Public Key attribute is supposed to be exactly 192 bytes
* in length. Allow couple of bytes shorter one to try to
* interoperate with implementations that do not use proper
* zero-padding.
*/
if (len < 190 || len > 192) {
wpa_printf(MSG_DEBUG,
"WPS: Ignore Public Key with unexpected length %u",
len);
break;
}
attr->public_key = pos;
attr->public_key_len = len;
break;
@@ -488,6 +526,11 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->num_cred++;
break;
case ATTR_SSID:
if (len > SSID_MAX_LEN) {
wpa_printf(MSG_DEBUG,
"WPS: Ignore too long SSID (len=%u)", len);
break;
}
attr->ssid = pos;
attr->ssid_len = len;
break;
@@ -495,14 +538,6 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->network_key = pos;
attr->network_key_len = len;
break;
case ATTR_EAP_TYPE:
attr->eap_type = pos;
attr->eap_type_len = len;
break;
case ATTR_EAP_IDENTITY:
attr->eap_identity = pos;
attr->eap_identity_len = len;
break;
case ATTR_AP_SETUP_LOCKED:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
@@ -582,7 +617,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
pos += 2;
len = WPA_GET_BE16(pos);
pos += 2;
wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
wpa_printf(MSG_EXCESSIVE, "WPS: attr type=0x%x len=%u",
type, len);
if (len > end - pos) {
wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");

View File

@@ -9,7 +9,7 @@
#ifndef WPS_ATTR_PARSE_H
#define WPS_ATTR_PARSE_H
#include "wps/wps.h"
#include "wps.h"
struct wps_parse_attr {
/* fixed length fields */
@@ -47,8 +47,6 @@ struct wps_parse_attr {
const u8 *network_idx; /* 1 octet */
const u8 *network_key_idx; /* 1 octet */
const u8 *mac_addr; /* ETH_ALEN (6) octets */
const u8 *key_prov_auto; /* 1 octet (Bool) */
const u8 *dot1x_enabled; /* 1 octet (Bool) */
const u8 *selected_registrar; /* 1 octet (Bool) */
const u8 *request_type; /* 1 octet */
const u8 *response_type; /* 1 octet */
@@ -57,50 +55,49 @@ struct wps_parse_attr {
const u8 *network_key_shareable; /* 1 octet (Bool) */
const u8 *request_to_enroll; /* 1 octet (Bool) */
const u8 *ap_channel; /* 2 octets */
const u8 *registrar_configuration_methods; /* 2 octets */
/* variable length fields */
const u8 *manufacturer;
size_t manufacturer_len;
const u8 *model_name;
size_t model_name_len;
const u8 *model_number;
size_t model_number_len;
const u8 *serial_number;
size_t serial_number_len;
const u8 *dev_name;
size_t dev_name_len;
const u8 *public_key;
size_t public_key_len;
const u8 *encr_settings;
size_t encr_settings_len;
const u8 *ssid; /* <= 32 octets */
size_t ssid_len;
const u8 *network_key; /* <= 64 octets */
size_t network_key_len;
const u8 *eap_type; /* <= 8 octets */
size_t eap_type_len;
const u8 *eap_identity; /* <= 64 octets */
size_t eap_identity_len;
const u8 *authorized_macs; /* <= 30 octets */
size_t authorized_macs_len;
const u8 *sec_dev_type_list; /* <= 128 octets */
size_t sec_dev_type_list_len;
const u8 *oob_dev_password; /* 38..54 octets */
size_t oob_dev_password_len;
u16 manufacturer_len;
u16 model_name_len;
u16 model_number_len;
u16 serial_number_len;
u16 dev_name_len;
u16 public_key_len;
u16 encr_settings_len;
u16 ssid_len;
u16 network_key_len;
u16 authorized_macs_len;
u16 sec_dev_type_list_len;
u16 oob_dev_password_len;
/* attributes that can occur multiple times */
#define MAX_CRED_COUNT 10
const u8 *cred[MAX_CRED_COUNT];
size_t cred_len[MAX_CRED_COUNT];
size_t num_cred;
#define MAX_REQ_DEV_TYPE_COUNT 10
const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
size_t num_req_dev_type;
unsigned int num_cred;
unsigned int num_req_dev_type;
unsigned int num_vendor_ext;
u16 cred_len[MAX_CRED_COUNT];
u16 vendor_ext_len[MAX_WPS_PARSE_VENDOR_EXT];
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];
size_t vendor_ext_len[MAX_WPS_PARSE_VENDOR_EXT];
size_t num_vendor_ext;
u8 multi_ap_ext;
};
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);

View File

@@ -5,11 +5,12 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "includes.h"
#include "common.h"
#include "crypto/sha256.h"
#include "wps/wps_i.h"
#include "wps_i.h"
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
@@ -38,8 +39,10 @@ int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
len[0] = wpabuf_len(wps->last_msg);
addr[1] = wpabuf_head(msg);
len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
if (hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len,
hash) < 0 ||
os_memcmp_const(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
return -1;
}
@@ -68,8 +71,8 @@ int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
return -1;
}
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash) < 0 ||
os_memcmp_const(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
return -1;
}
@@ -169,7 +172,7 @@ static int wps_process_cred_network_key(struct wps_credential *cred,
if (key == NULL) {
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
"Network Key");
if (cred->auth_type == WPS_WIFI_AUTH_OPEN &&
if (cred->auth_type == WPS_AUTH_OPEN &&
cred->encr_type == WPS_ENCR_NONE) {
wpa_printf(MSG_DEBUG, "WPS: Workaround - Allow "
"missing mandatory Network Key attribute "
@@ -205,70 +208,6 @@ static int wps_process_cred_mac_addr(struct wps_credential *cred,
}
static int wps_process_cred_eap_type(struct wps_credential *cred,
const u8 *eap_type, size_t eap_type_len)
{
if (eap_type == NULL)
return 0; /* optional attribute */
wpa_hexdump(MSG_DEBUG, "WPS: EAP Type", eap_type, eap_type_len);
return 0;
}
static int wps_process_cred_eap_identity(struct wps_credential *cred,
const u8 *identity,
size_t identity_len)
{
if (identity == NULL)
return 0; /* optional attribute */
wpa_hexdump_ascii(MSG_DEBUG, "WPS: EAP Identity",
identity, identity_len);
return 0;
}
static int wps_process_cred_key_prov_auto(struct wps_credential *cred,
const u8 *key_prov_auto)
{
if (key_prov_auto == NULL)
return 0; /* optional attribute */
wpa_printf(MSG_DEBUG, "WPS: Key Provided Automatically: %d",
*key_prov_auto);
return 0;
}
static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
const u8 *dot1x_enabled)
{
if (dot1x_enabled == NULL)
return 0; /* optional attribute */
wpa_printf(MSG_DEBUG, "WPS: 802.1X Enabled: %d", *dot1x_enabled);
return 0;
}
static int wps_process_cred_ap_channel(struct wps_credential *cred,
const u8 *ap_channel)
{
if (ap_channel == NULL)
return 0; /* optional attribute */
cred->ap_channel = WPA_GET_BE16(ap_channel);
wpa_printf(MSG_DEBUG, "WPS: AP Channel: %u", cred->ap_channel);
return 0;
}
static int wps_workaround_cred_key(struct wps_credential *cred)
{
if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
@@ -291,6 +230,16 @@ static int wps_workaround_cred_key(struct wps_credential *cred)
cred->key_len--;
#endif /* CONFIG_WPS_STRICT */
}
if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
(cred->key_len < 8 || has_ctrl_char(cred->key, cred->key_len))) {
wpa_printf(MSG_INFO, "WPS: Reject credential with invalid WPA/WPA2-Personal passphrase");
wpa_hexdump_ascii_key(MSG_INFO, "WPS: Network Key",
cred->key, cred->key_len);
return -1;
}
return 0;
}
@@ -308,14 +257,7 @@ int wps_process_cred(struct wps_parse_attr *attr,
wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
wps_process_cred_network_key(cred, attr->network_key,
attr->network_key_len) ||
wps_process_cred_mac_addr(cred, attr->mac_addr) ||
wps_process_cred_eap_type(cred, attr->eap_type,
attr->eap_type_len) ||
wps_process_cred_eap_identity(cred, attr->eap_identity,
attr->eap_identity_len) ||
wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled) ||
wps_process_cred_ap_channel(cred, attr->ap_channel))
wps_process_cred_mac_addr(cred, attr->mac_addr))
return -1;
return wps_workaround_cred_key(cred);

View File

@@ -5,19 +5,21 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include <string.h>
#include "utils/includes.h"
#include "utils/common.h"
#include "includes.h"
#include "common.h"
#include "common/defs.h"
#include "common/ieee802_11_common.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
#include "crypto/dh_group5.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "crypto/dh_group5.h"
#include "crypto/random.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
#include "wps/wps_i.h"
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
const char *label, u8 *res, size_t res_len)
@@ -88,12 +90,12 @@ int wps_derive_keys(struct wps_data *wps)
}
/* Own DH private key is not needed anymore */
/*
/*
* due to the public key calculated when wps start, it will not calculate anymore even when we build M1 message, also calculate the key need take a long time
* which would cause WPS fail, so we clean the key after WPS finished .
*/
#ifndef ESP32_WORKAROUND
wpabuf_free(wps->dh_privkey);
wpabuf_clear_free(wps->dh_privkey);
wps->dh_privkey = NULL;
#endif //ESP32_WORKAROUND
@@ -102,10 +104,9 @@ int wps_derive_keys(struct wps_data *wps)
/* DHKey = SHA-256(g^AB mod p) */
addr[0] = wpabuf_head(dh_shared);
len[0] = wpabuf_len(dh_shared);
sha256_vector(1, addr, len, dhkey);
wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
wpabuf_free(dh_shared);
wpabuf_clear_free(dh_shared);
/* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
addr[0] = wps->nonce_e;
@@ -134,23 +135,26 @@ int wps_derive_keys(struct wps_data *wps)
}
void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
int wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
size_t dev_passwd_len)
{
u8 hash[SHA256_MAC_LEN];
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
(dev_passwd_len + 1) / 2, hash);
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
(dev_passwd_len + 1) / 2, hash) < 0)
return -1;
os_memcpy(wps->psk1, hash, WPS_PSK_LEN);
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN,
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN,
dev_passwd + (dev_passwd_len + 1) / 2,
dev_passwd_len / 2, hash);
dev_passwd_len / 2, hash) < 0)
return -1;
os_memcpy(wps->psk2, hash, WPS_PSK_LEN);
wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password",
dev_passwd, dev_passwd_len);
wpa_hexdump_key(MSG_DEBUG, "WPS: PSK1", wps->psk1, WPS_PSK_LEN);
wpa_hexdump_key(MSG_DEBUG, "WPS: PSK2", wps->psk2, WPS_PSK_LEN);
return 0;
}
@@ -176,10 +180,9 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len);
wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size);
wpa_printf(MSG_DEBUG, "WPS: AES Decrypt setting");
if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
wpabuf_len(decrypted))) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
@@ -190,14 +193,14 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
pad = *pos;
if (pad > wpabuf_len(decrypted)) {
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value");
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
for (i = 0; i < pad; i++) {
if (*pos-- != pad) {
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad "
"string");
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
return NULL;
}
}
@@ -206,7 +209,7 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
return decrypted;
}
#ifdef CONFIG_WPS_PIN
/**
* wps_pin_checksum - Compute PIN checksum
* @pin: Seven digit PIN (i.e., eight digit PIN without the checksum digit)
@@ -241,18 +244,18 @@ unsigned int wps_pin_valid(unsigned int pin)
* wps_generate_pin - Generate a random PIN
* Returns: Eight digit PIN (i.e., including the checksum digit)
*/
unsigned int wps_generate_pin(void)
int wps_generate_pin(unsigned int *pin)
{
unsigned int val;
/* Generate seven random digits for the PIN */
if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) {
if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0)
return -1;
}
val %= 10000000;
/* Append checksum digit */
return val * 10 + wps_pin_checksum(val);
*pin = val * 10 + wps_pin_checksum(val);
return 0;
}
@@ -270,58 +273,51 @@ int wps_pin_str_valid(const char *pin)
len = p - pin;
return len == 4 || len == 8;
}
#endif
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
u16 config_error, u16 error_indication)
u16 config_error, u16 error_indication, const u8 *mac_addr)
{
union wps_event_data *data;
union wps_event_data data;
data = (union wps_event_data *)os_zalloc(sizeof(union wps_event_data));
if (data == NULL)
return;
if (wps->event_cb == NULL) {
os_free(data);
return;
}
os_memset(data, 0, sizeof(union wps_event_data));
data->fail.msg = msg;
data->fail.config_error = config_error;
data->fail.error_indication = error_indication;
wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, data);
os_free(data);
}
void wps_success_event(struct wps_context *wps)
{
if (wps->event_cb == NULL)
return;
wps->event_cb(wps->cb_ctx, WPS_EV_SUCCESS, NULL);
os_memset(&data, 0, sizeof(data));
data.fail.msg = msg;
data.fail.config_error = config_error;
data.fail.error_indication = error_indication;
os_memcpy(data.fail.peer_macaddr, mac_addr, ETH_ALEN);
wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
}
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part)
void wps_success_event(struct wps_context *wps, const u8 *mac_addr)
{
union wps_event_data *data;
union wps_event_data data;
data = (union wps_event_data *)os_zalloc(sizeof(union wps_event_data));
if (data == NULL)
if (wps->event_cb == NULL)
return;
if (wps->event_cb == NULL) {
os_free(data);
return;
}
os_memset(&data, 0, sizeof(data));
os_memcpy(data.success.peer_macaddr, mac_addr, ETH_ALEN);
wps->event_cb(wps->cb_ctx, WPS_EV_SUCCESS, &data);
}
os_memset(data, 0, sizeof(union wps_event_data));
data->pwd_auth_fail.enrollee = enrollee;
data->pwd_auth_fail.part = part;
wps->event_cb(wps->cb_ctx, WPS_EV_PWD_AUTH_FAIL, data);
os_free(data);
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part,
const u8 *mac_addr)
{
union wps_event_data data;
if (wps->event_cb == NULL)
return;
os_memset(&data, 0, sizeof(data));
data.pwd_auth_fail.enrollee = enrollee;
data.pwd_auth_fail.part = part;
os_memcpy(data.pwd_auth_fail.peer_macaddr, mac_addr, ETH_ALEN);
wps->event_cb(wps->cb_ctx, WPS_EV_PWD_AUTH_FAIL, &data);
}
@@ -343,38 +339,78 @@ void wps_pbc_timeout_event(struct wps_context *wps)
}
void wps_pbc_active_event(struct wps_context *wps)
{
if (wps->event_cb == NULL)
return;
wps->event_cb(wps->cb_ctx, WPS_EV_PBC_ACTIVE, NULL);
}
void wps_pbc_disable_event(struct wps_context *wps)
{
if (wps->event_cb == NULL)
return;
wps->event_cb(wps->cb_ctx, WPS_EV_PBC_DISABLE, NULL);
}
#ifdef CONFIG_WPS_OOB
struct wpabuf * wps_get_oob_cred(struct wps_context *wps)
struct wpabuf * wps_get_oob_cred(struct wps_context *wps, int rf_band,
int channel)
{
struct wps_data *data;
struct wps_data data;
struct wpabuf *plain;
data = (struct wps_data *)os_zalloc(sizeof(struct wps_data));
if (data == NULL)
return NULL;
plain = wpabuf_alloc(500);
if (plain == NULL) {
os_free(data);
wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
"credential");
return NULL;
}
os_memset(data, 0, sizeof(struct wps_data));
data->wps = wps;
data->auth_type = wps->auth_types;
data->encr_type = wps->encr_types;
if (wps_build_version(plain) ||
wps_build_cred(data, plain) ||
wps_build_wfa_ext(plain, 0, NULL, 0)) {
wpabuf_free(plain);
os_free(data);
os_memset(&data, 0, sizeof(data));
data.wps = wps;
data.auth_type = wps->auth_types;
data.encr_type = wps->encr_types;
if (wps_build_cred(&data, plain) ||
(rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
(channel && wps_build_ap_channel(plain, channel)) ||
wps_build_mac_addr(plain, wps->dev.mac_addr) ||
wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
os_free(data.new_psk);
wpabuf_clear_free(plain);
return NULL;
}
os_free(data);
if (wps->wps_state == WPS_STATE_NOT_CONFIGURED && data.new_psk &&
wps->ap) {
struct wps_credential cred;
wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
"on credential token generation");
os_memset(&cred, 0, sizeof(cred));
os_memcpy(cred.ssid, wps->ssid, wps->ssid_len);
cred.ssid_len = wps->ssid_len;
cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
os_memcpy(cred.key, data.new_psk, data.new_psk_len);
cred.key_len = data.new_psk_len;
wps->wps_state = WPS_STATE_CONFIGURED;
wpa_hexdump_ascii_key(MSG_DEBUG,
"WPS: Generated random passphrase",
data.new_psk, data.new_psk_len);
if (wps->cred_cb)
wps->cred_cb(wps->cb_ctx, &cred);
}
os_free(data.new_psk);
return plain;
}
@@ -390,13 +426,12 @@ struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id,
if (data == NULL)
return NULL;
if (wps_build_version(data) ||
wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
wps_build_wfa_ext(data, 0, NULL, 0)) {
wps_build_wfa_ext(data, 0, NULL, 0, 0)) {
wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
"token");
wpabuf_free(data);
wpabuf_clear_free(data);
return NULL;
}
@@ -438,13 +473,13 @@ int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN])
/* <categ>-<OUI>-<subcateg> */
WPA_PUT_BE16(dev_type, atoi(str));
pos = (char *)os_strchr(str, '-');
pos = os_strchr(str, '-');
if (pos == NULL)
return -1;
pos++;
if (hexstr2bin(pos, &dev_type[2], 4))
return -1;
pos = (char *)os_strchr(pos, '-');
pos = os_strchr(pos, '-');
if (pos == NULL)
return -1;
pos++;
@@ -460,10 +495,10 @@ char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
{
int ret;
ret = snprintf(buf, buf_len, "%u-%08X-%u",
ret = os_snprintf(buf, buf_len, "%u-%08X-%u",
WPA_GET_BE16(dev_type), WPA_GET_BE32(&dev_type[2]),
WPA_GET_BE16(&dev_type[6]));
if (ret < 0 || (unsigned int) ret >= buf_len)
if (os_snprintf_error(buf_len, ret))
return NULL;
return buf;
@@ -502,15 +537,16 @@ u16 wps_config_methods_str2bin(const char *str)
{
u16 methods = 0;
if (str == NULL) {
if (str == NULL || str[0] == '\0') {
/* Default to enabling methods based on build configuration */
methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
#ifdef CONFIG_WPS2
methods |= WPS_CONFIG_VIRT_DISPLAY;
#endif /* CONFIG_WPS2 */
#ifdef CONFIG_WPS_NFC
methods |= WPS_CONFIG_NFC_INTERFACE;
#endif /* CONFIG_WPS_NFC */
#ifdef CONFIG_P2P
methods |= WPS_CONFIG_P2PS;
#endif /* CONFIG_P2P */
} else {
if (os_strstr(str, "ethernet"))
methods |= WPS_CONFIG_ETHERNET;
@@ -528,7 +564,6 @@ u16 wps_config_methods_str2bin(const char *str)
methods |= WPS_CONFIG_PUSHBUTTON;
if (os_strstr(str, "keypad"))
methods |= WPS_CONFIG_KEYPAD;
#ifdef CONFIG_WPS2
if (os_strstr(str, "virtual_display"))
methods |= WPS_CONFIG_VIRT_DISPLAY;
if (os_strstr(str, "physical_display"))
@@ -537,7 +572,8 @@ u16 wps_config_methods_str2bin(const char *str)
methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
if (os_strstr(str, "physical_push_button"))
methods |= WPS_CONFIG_PHY_PUSHBUTTON;
#endif /* CONFIG_WPS2 */
if (os_strstr(str, "p2ps"))
methods |= WPS_CONFIG_P2PS;
}
return methods;
@@ -558,7 +594,7 @@ struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
wps_build_msg_type(msg, WPS_WSC_ACK) ||
wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) ||
wps_build_wfa_ext(msg, 0, NULL, 0)) {
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
@@ -582,7 +618,7 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) ||
wps_build_config_error(msg, wps->config_error) ||
wps_build_wfa_ext(msg, 0, NULL, 0)) {
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
@@ -592,12 +628,60 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
#ifdef CONFIG_WPS_NFC
struct wpabuf * wps_nfc_token_build(int ndef, int id, struct wpabuf *pubkey,
struct wpabuf *dev_pw)
{
struct wpabuf *ret;
if (pubkey == NULL || dev_pw == NULL)
return NULL;
ret = wps_build_nfc_pw_token(id, pubkey, dev_pw);
if (ndef && ret) {
struct wpabuf *tmp;
tmp = ndef_build_wifi(ret);
wpabuf_free(ret);
if (tmp == NULL)
return NULL;
ret = tmp;
}
return ret;
}
int wps_nfc_gen_dh(struct wpabuf **pubkey, struct wpabuf **privkey)
{
struct wpabuf *priv = NULL, *pub = NULL;
void *dh_ctx;
dh_ctx = dh5_init(&priv, &pub);
if (dh_ctx == NULL)
return -1;
pub = wpabuf_zeropad(pub, 192);
if (pub == NULL) {
wpabuf_free(priv);
dh5_free(dh_ctx);
return -1;
}
wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub);
dh5_free(dh_ctx);
wpabuf_free(*pubkey);
*pubkey = pub;
wpabuf_clear_free(*privkey);
*privkey = priv;
return 0;
}
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
struct wpabuf **privkey,
struct wpabuf **dev_pw)
{
struct wpabuf *priv = NULL, *pub = NULL, *pw, *ret;
void *dh_ctx;
struct wpabuf *pw;
u16 val;
pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN);
@@ -611,31 +695,225 @@ struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
return NULL;
}
dh_ctx = dh5_init(&priv, &pub);
if (dh_ctx == NULL) {
if (wps_nfc_gen_dh(pubkey, privkey) < 0) {
wpabuf_free(pw);
return NULL;
}
dh5_free(dh_ctx);
*id = 0x10 + val % 0xfff0;
wpabuf_free(*pubkey);
*pubkey = pub;
wpabuf_free(*privkey);
*privkey = priv;
wpabuf_free(*dev_pw);
wpabuf_clear_free(*dev_pw);
*dev_pw = pw;
ret = wps_build_nfc_pw_token(*id, *pubkey, *dev_pw);
if (ndef && ret) {
struct wpabuf *tmp;
tmp = ndef_build_wifi(ret);
wpabuf_free(ret);
if (tmp == NULL)
return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw);
}
struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey)
{
struct wpabuf *msg;
void *len;
if (ctx == NULL)
return NULL;
wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
"handover request");
if (nfc_dh_pubkey == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
"configured");
return NULL;
ret = tmp;
}
return ret;
msg = wpabuf_alloc(1000);
if (msg == NULL)
return msg;
len = wpabuf_put(msg, 2);
if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
nfc_dh_pubkey, NULL, 0) ||
wps_build_uuid_e(msg, ctx->uuid) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
WPA_PUT_BE16(len, wpabuf_len(msg) - 2);
return msg;
}
static int wps_build_ssid(struct wpabuf *msg, struct wps_context *wps)
{
wpa_printf(MSG_DEBUG, "WPS: * SSID");
wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID in Connection Handover Select",
wps->ssid, wps->ssid_len);
wpabuf_put_be16(msg, ATTR_SSID);
wpabuf_put_be16(msg, wps->ssid_len);
wpabuf_put_data(msg, wps->ssid, wps->ssid_len);
return 0;
}
static int wps_build_ap_freq(struct wpabuf *msg, int freq)
{
enum hostapd_hw_mode mode;
u8 channel, rf_band;
u16 ap_channel;
if (freq <= 0)
return 0;
mode = ieee80211_freq_to_chan(freq, &channel);
if (mode == NUM_HOSTAPD_MODES)
return 0; /* Unknown channel */
if (mode == HOSTAPD_MODE_IEEE80211G || mode == HOSTAPD_MODE_IEEE80211B)
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;
if (wps_build_rf_bands_attr(msg, rf_band) ||
wps_build_ap_channel(msg, ap_channel))
return -1;
return 0;
}
struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey,
const u8 *bssid, int freq)
{
struct wpabuf *msg;
void *len;
if (ctx == NULL)
return NULL;
wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
"handover select");
if (nfc_dh_pubkey == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
"configured");
return NULL;
}
msg = wpabuf_alloc(1000);
if (msg == NULL)
return msg;
len = wpabuf_put(msg, 2);
if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
nfc_dh_pubkey, NULL, 0) ||
wps_build_ssid(msg, ctx) ||
wps_build_ap_freq(msg, freq) ||
(bssid && wps_build_mac_addr(msg, bssid)) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
WPA_PUT_BE16(len, wpabuf_len(msg) - 2);
return msg;
}
struct wpabuf * wps_build_nfc_handover_req_p2p(struct wps_context *ctx,
struct wpabuf *nfc_dh_pubkey)
{
struct wpabuf *msg;
if (ctx == NULL)
return NULL;
wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
"handover request (P2P)");
if (nfc_dh_pubkey == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No NFC DH Public Key configured");
return NULL;
}
msg = wpabuf_alloc(1000);
if (msg == NULL)
return msg;
if (wps_build_manufacturer(&ctx->dev, msg) ||
wps_build_model_name(&ctx->dev, msg) ||
wps_build_model_number(&ctx->dev, msg) ||
wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
nfc_dh_pubkey, NULL, 0) ||
wps_build_rf_bands(&ctx->dev, msg, 0) ||
wps_build_serial_number(&ctx->dev, msg) ||
wps_build_uuid_e(msg, ctx->uuid) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
return msg;
}
struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx,
int nfc_dev_pw_id,
struct wpabuf *nfc_dh_pubkey,
struct wpabuf *nfc_dev_pw)
{
struct wpabuf *msg;
const u8 *dev_pw;
size_t dev_pw_len;
if (ctx == NULL)
return NULL;
wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
"handover select (P2P)");
if (nfc_dh_pubkey == NULL ||
(nfc_dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER &&
nfc_dev_pw == NULL)) {
wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
"configured");
return NULL;
}
msg = wpabuf_alloc(1000);
if (msg == NULL)
return msg;
if (nfc_dev_pw) {
dev_pw = wpabuf_head(nfc_dev_pw);
dev_pw_len = wpabuf_len(nfc_dev_pw);
} else {
dev_pw = NULL;
dev_pw_len = 0;
}
if (wps_build_manufacturer(&ctx->dev, msg) ||
wps_build_model_name(&ctx->dev, msg) ||
wps_build_model_number(&ctx->dev, msg) ||
wps_build_oob_dev_pw(msg, nfc_dev_pw_id, nfc_dh_pubkey,
dev_pw, dev_pw_len) ||
wps_build_rf_bands(&ctx->dev, msg, 0) ||
wps_build_serial_number(&ctx->dev, msg) ||
wps_build_uuid_e(msg, ctx->uuid) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
return msg;
}
#endif /* CONFIG_WPS_NFC */

View File

@@ -12,16 +12,17 @@
#ifdef CONFIG_WPS_TESTING
extern int wps_version_number;
extern int wps_testing_dummy_cred;
extern int wps_testing_stub_cred;
extern int wps_corrupt_pkhash;
extern int wps_force_auth_types_in_use;
extern u16 wps_force_auth_types;
extern int wps_force_encr_types_in_use;
extern u16 wps_force_encr_types;
#define WPS_VERSION wps_version_number
#else /* CONFIG_WPS_TESTING */
#ifdef CONFIG_WPS2
#define WPS_VERSION 0x20
#else /* CONFIG_WPS2 */
#define WPS_VERSION 0x10
#endif /* CONFIG_WPS2 */
#endif /* CONFIG_WPS_TESTING */
@@ -44,6 +45,11 @@ extern int wps_testing_dummy_cred;
#define WPS_OOB_DEVICE_PASSWORD_MIN_LEN 16
#define WPS_OOB_DEVICE_PASSWORD_LEN 32
#define WPS_OOB_PUBKEY_HASH_LEN 20
#define WPS_DEV_NAME_MAX_LEN 32
#define WPS_MANUFACTURER_MAX_LEN 64
#define WPS_MODEL_NAME_MAX_LEN 32
#define WPS_MODEL_NUMBER_MAX_LEN 32
#define WPS_SERIAL_NUMBER_MAX_LEN 32
/* Attribute Types */
enum wps_attribute {
@@ -145,7 +151,9 @@ enum {
WFA_ELEM_AUTHORIZEDMACS = 0x01,
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
WFA_ELEM_MULTI_AP = 0x06
};
/* Device Password ID */
@@ -155,13 +163,9 @@ enum wps_dev_password_id {
DEV_PW_MACHINE_SPECIFIED = 0x0002,
DEV_PW_REKEY = 0x0003,
DEV_PW_PUSHBUTTON = 0x0004,
DEV_PW_REGISTRAR_SPECIFIED = 0x0005
};
/* WPS message flag */
enum wps_msg_flag {
WPS_MSG_FLAG_MORE = 0x01,
WPS_MSG_FLAG_LEN = 0x02
DEV_PW_REGISTRAR_SPECIFIED = 0x0005,
DEV_PW_NFC_CONNECTION_HANDOVER = 0x0007,
DEV_PW_P2PS_DEFAULT = 0x0008
};
/* Message Type */
@@ -184,18 +188,18 @@ enum wps_msg_type {
};
/* Authentication Type Flags */
#define WPS_WIFI_AUTH_OPEN 0x0001
#define WPS_AUTH_OPEN 0x0001
#define WPS_AUTH_WPAPSK 0x0002
#define WPS_AUTH_SHARED 0x0004
#define WPS_AUTH_SHARED 0x0004 /* deprecated */
#define WPS_AUTH_WPA 0x0008
#define WPS_AUTH_WPA2 0x0010
#define WPS_AUTH_WPA2PSK 0x0020
#define WPS_AUTH_TYPES (WPS_WIFI_AUTH_OPEN | WPS_AUTH_WPAPSK | WPS_AUTH_SHARED | \
#define WPS_AUTH_TYPES (WPS_AUTH_OPEN | WPS_AUTH_WPAPSK | WPS_AUTH_SHARED | \
WPS_AUTH_WPA | WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)
/* Encryption Type Flags */
#define WPS_ENCR_NONE 0x0001
#define WPS_ENCR_WEP 0x0002
#define WPS_ENCR_WEP 0x0002 /* deprecated */
#define WPS_ENCR_TKIP 0x0004
#define WPS_ENCR_AES 0x0008
#define WPS_ENCR_TYPES (WPS_ENCR_NONE | WPS_ENCR_WEP | WPS_ENCR_TKIP | \
@@ -221,7 +225,9 @@ enum wps_config_error {
WPS_CFG_SETUP_LOCKED = 15,
WPS_CFG_MSG_TIMEOUT = 16,
WPS_CFG_REG_SESS_TIMEOUT = 17,
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18,
WPS_CFG_60G_CHAN_NOT_SUPPORTED = 19,
WPS_CFG_PUBLIC_KEY_HASH_MISMATCH = 20
};
/* Vendor specific Error Indication for WPS event messages */
@@ -229,12 +235,14 @@ enum wps_error_indication {
WPS_EI_NO_ERROR,
WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
WPS_EI_SECURITY_WEP_PROHIBITED,
WPS_EI_AUTH_FAILURE,
NUM_WPS_EI_VALUES
};
/* RF Bands */
#define WPS_RF_24GHZ 0x01
#define WPS_RF_50GHZ 0x02
#define WPS_RF_60GHZ 0x04
/* Config Methods */
#define WPS_CONFIG_USBA 0x0001
@@ -246,12 +254,11 @@ enum wps_error_indication {
#define WPS_CONFIG_NFC_INTERFACE 0x0040
#define WPS_CONFIG_PUSHBUTTON 0x0080
#define WPS_CONFIG_KEYPAD 0x0100
#ifdef CONFIG_WPS2
#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
#define WPS_CONFIG_P2PS 0x1000
#define WPS_CONFIG_VIRT_DISPLAY 0x2008
#define WPS_CONFIG_PHY_DISPLAY 0x4008
#endif /* CONFIG_WPS2 */
/* Connection Type Flags */
#define WPS_CONN_ESS 0x01
@@ -285,7 +292,8 @@ enum wps_dev_categ {
WPS_DEV_DISPLAY = 7,
WPS_DEV_MULTIMEDIA = 8,
WPS_DEV_GAMING = 9,
WPS_DEV_PHONE = 10
WPS_DEV_PHONE = 10,
WPS_DEV_AUDIO = 11,
};
enum wps_dev_subcateg {
@@ -334,8 +342,4 @@ enum wps_response_type {
#define WPS_MAX_AUTHORIZED_MACS 5
#define WPS_IGNORE_SEL_REG_MAX_CNT 4
#define WPS_MAX_DIS_AP_NUM 10
#endif /* WPS_DEFS_H */

View File

@@ -5,11 +5,13 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "wps/wps_i.h"
#include "wps/wps_dev_attr.h"
#include "includes.h"
#include "common.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg)
{
@@ -83,8 +85,7 @@ int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg)
}
static int wps_build_serial_number(struct wps_device_data *dev,
struct wpabuf *msg)
int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg)
{
size_t len;
wpa_printf(MSG_DEBUG, "WPS: * Serial Number");
@@ -215,13 +216,10 @@ int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
}
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg)
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
u8 rf_band)
{
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", dev->rf_bands);
wpabuf_put_be16(msg, ATTR_RF_BANDS);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, dev->rf_bands);
return 0;
return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
}
@@ -244,6 +242,21 @@ int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
}
int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg)
{
if (!dev->application_ext)
return 0;
wpa_hexdump_buf(MSG_DEBUG, "WPS: * Application Extension",
dev->application_ext);
wpabuf_put_be16(msg, ATTR_APPLICATION_EXT);
wpabuf_put_be16(msg, wpabuf_len(dev->application_ext));
wpabuf_put_buf(msg, dev->application_ext);
return 0;
}
static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
size_t str_len)
{
@@ -255,11 +268,9 @@ static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
os_free(dev->manufacturer);
dev->manufacturer = (char *)os_malloc(str_len + 1);
dev->manufacturer = dup_binstr(str, str_len);
if (dev->manufacturer == NULL)
return -1;
os_memcpy(dev->manufacturer, str, str_len);
dev->manufacturer[str_len] = '\0';
return 0;
}
@@ -276,11 +287,9 @@ static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
os_free(dev->model_name);
dev->model_name = (char *)os_malloc(str_len + 1);
dev->model_name = dup_binstr(str, str_len);
if (dev->model_name == NULL)
return -1;
os_memcpy(dev->model_name, str, str_len);
dev->model_name[str_len] = '\0';
return 0;
}
@@ -297,11 +306,9 @@ static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
os_free(dev->model_number);
dev->model_number = (char *)os_malloc(str_len + 1);
dev->model_number = dup_binstr(str, str_len);
if (dev->model_number == NULL)
return -1;
os_memcpy(dev->model_number, str, str_len);
dev->model_number[str_len] = '\0';
return 0;
}
@@ -318,11 +325,9 @@ static int wps_process_serial_number(struct wps_device_data *dev,
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
os_free(dev->serial_number);
dev->serial_number = (char *)os_malloc(str_len + 1);
dev->serial_number = dup_binstr(str, str_len);
if (dev->serial_number == NULL)
return -1;
os_memcpy(dev->serial_number, str, str_len);
dev->serial_number[str_len] = '\0';
return 0;
}
@@ -339,11 +344,9 @@ static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
os_free(dev->device_name);
dev->device_name = (char *)os_malloc(str_len + 1);
dev->device_name = dup_binstr(str, str_len);
if (dev->device_name == NULL)
return -1;
os_memcpy(dev->device_name, str, str_len);
dev->device_name[str_len] = '\0';
return 0;
}
@@ -352,12 +355,21 @@ static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
static int wps_process_primary_dev_type(struct wps_device_data *dev,
const u8 *dev_type)
{
#ifdef DEBUG_PRINT
char devtype[WPS_DEV_TYPE_BUFSIZE];
#endif /* CONFIG_NO_STDOUT_DEBUG */
if (dev_type == NULL) {
wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
return -1;
}
os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
#ifdef DEBUG_PRINT
wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
wps_dev_type_bin2str(dev->pri_dev_type, devtype,
sizeof(devtype)));
#endif
return 0;
}
@@ -395,6 +407,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) {
@@ -409,25 +429,6 @@ int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
}
void wps_device_data_dup(struct wps_device_data *dst,
const struct wps_device_data *src)
{
if (src->device_name)
dst->device_name = os_strdup(src->device_name);
if (src->manufacturer)
dst->manufacturer = os_strdup(src->manufacturer);
if (src->model_name)
dst->model_name = os_strdup(src->model_name);
if (src->model_number)
dst->model_number = os_strdup(src->model_number);
if (src->serial_number)
dst->serial_number = os_strdup(src->serial_number);
os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
dst->os_version = src->os_version;
dst->rf_bands = src->rf_bands;
}
void wps_device_data_free(struct wps_device_data *dev)
{
os_free(dev->device_name);
@@ -440,4 +441,6 @@ void wps_device_data_free(struct wps_device_data *dev)
dev->model_number = NULL;
os_free(dev->serial_number);
dev->serial_number = NULL;
wpabuf_free(dev->application_ext);
dev->application_ext = NULL;
}

View File

@@ -14,11 +14,13 @@ struct wps_parse_attr;
int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_model_name(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
u8 rf_band);
int wps_build_primary_dev_type(struct wps_device_data *dev,
struct wpabuf *msg);
int wps_build_secondary_dev_type(struct wps_device_data *dev,
@@ -27,11 +29,11 @@ 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_dup(struct wps_device_data *dst,
const struct wps_device_data *src);
void wps_device_data_free(struct wps_device_data *dev);
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
unsigned int num_req_dev_types,
const u8 *req_dev_types);

View File

@@ -5,28 +5,17 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/ets_sys.h" // for ets_timer_disarm
#endif
#include "utils/includes.h"
#include "utils/common.h"
#include "includes.h"
#include "common.h"
#include "crypto/crypto.h"
#include "crypto/sha256.h"
#include "crypto/random.h"
#include "wps/wps_i.h"
#include "wps/wps.h"
#include "wps/wps_dev_attr.h"
static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg) {
wpa_printf(MSG_DEBUG, "WPS: * MAC Address");
wpabuf_put_be16(msg, ATTR_MAC_ADDR);
wpabuf_put_be16(msg, ETH_ALEN);
wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
return 0;
}
#include "wps_i.h"
#include "wps_dev_attr.h"
#include "esp_wps_i.h"
static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
{
@@ -117,6 +106,7 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
{
struct wpabuf *msg;
u16 config_methods;
u8 multi_ap_backhaul_sta = 0;
if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
return NULL;
@@ -142,30 +132,36 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
* workaround.
*/
config_methods &= ~WPS_CONFIG_PUSHBUTTON;
#ifdef CONFIG_WPS2
config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
WPS_CONFIG_PHY_PUSHBUTTON);
#endif /* CONFIG_WPS2 */
}
if (wps->multi_ap_backhaul_sta)
multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
if (wps_build_version(msg) ||
wps_build_msg_type(msg, WPS_M1) ||
wps_build_uuid_e(msg, wps->uuid_e) ||
wps_build_mac_addr(wps, msg) ||
wps_build_mac_addr(msg, wps->mac_addr_e) ||
wps_build_enrollee_nonce(wps, msg) ||
wps_build_public_key(wps, msg, WPS_CALC_KEY_NO_CALC) ||
wps_build_public_key(wps, msg) ||
wps_build_auth_type_flags(wps, msg) ||
wps_build_encr_type_flags(wps, msg) ||
wps_build_conn_type_flags(wps, msg) ||
wps_build_config_methods(msg, config_methods) ||
wps_build_wps_state(wps, msg) ||
wps_build_device_attrs(&wps->wps->dev, msg) ||
wps_build_rf_bands(&wps->wps->dev, msg) ||
wps_build_rf_bands(&wps->wps->dev, msg,
#ifdef ESP_SUPPLICANT
wps->wps->dev.rf_bands) ||
#else
wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
#endif
wps_build_assoc_state(wps, msg) ||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_os_version(&wps->wps->dev, msg) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
wpabuf_free(msg);
return NULL;
@@ -186,7 +182,14 @@ static struct wpabuf * wps_build_m3(struct wps_data *wps)
wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
return NULL;
}
wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
return NULL;
if (wps->wps->ap && random_pool_ready() != 1) {
wpa_printf(MSG_INFO,
"WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
return NULL;
}
msg = wpabuf_alloc(1000);
if (msg == NULL)
@@ -196,7 +199,7 @@ static struct wpabuf * wps_build_m3(struct wps_data *wps)
wps_build_msg_type(msg, WPS_M3) ||
wps_build_registrar_nonce(wps, msg) ||
wps_build_e_hash(wps, msg) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(msg);
return NULL;
@@ -229,13 +232,13 @@ static struct wpabuf * wps_build_m5(struct wps_data *wps)
wps_build_e_snonce1(wps, plain) ||
wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
wps->state = RECV_M6;
return msg;
@@ -254,17 +257,19 @@ static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
{
u16 auth_type = wps->wps->auth_types;
u16 auth_type = wps->wps->ap_auth_type;
/* Select the best authentication type */
/*
* Work around issues with Windows 7 WPS implementation not liking
* multiple Authentication Type bits in M7 AP Settings attribute by
* showing only the most secure option from current configuration.
*/
if (auth_type & WPS_AUTH_WPA2PSK)
auth_type = WPS_AUTH_WPA2PSK;
else if (auth_type & WPS_AUTH_WPAPSK)
auth_type = WPS_AUTH_WPAPSK;
else if (auth_type & WPS_WIFI_AUTH_OPEN)
auth_type = WPS_WIFI_AUTH_OPEN;
else if (auth_type & WPS_AUTH_SHARED)
auth_type = WPS_AUTH_SHARED;
else if (auth_type & WPS_AUTH_OPEN)
auth_type = WPS_AUTH_OPEN;
wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)", auth_type);
wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
@@ -276,19 +281,18 @@ static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
{
u16 encr_type = wps->wps->encr_types;
u16 encr_type = wps->wps->ap_encr_type;
/* Select the best encryption type */
if (wps->wps->auth_types & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
/*
* Work around issues with Windows 7 WPS implementation not liking
* multiple Encryption Type bits in M7 AP Settings attribute by
* showing only the most secure option from current configuration.
*/
if (wps->wps->ap_auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
if (encr_type & WPS_ENCR_AES)
encr_type = WPS_ENCR_AES;
else if (encr_type & WPS_ENCR_TKIP)
encr_type = WPS_ENCR_TKIP;
} else {
if (encr_type & WPS_ENCR_WEP)
encr_type = WPS_ENCR_WEP;
else if (encr_type & WPS_ENCR_NONE)
encr_type = WPS_ENCR_NONE;
}
wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)", encr_type);
@@ -301,7 +305,37 @@ 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)
{
wpa_printf(MSG_DEBUG, "WPS: * Network Key");
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_pool_ready() != 1 ||
random_get_bytes(psk, sizeof(psk)) < 0) {
wpa_printf(MSG_INFO,
"WPS: Could not generate random PSK");
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);
#ifdef CONFIG_WPS_REGISTRAR
if (wps->wps->registrar) {
wps_cb_new_psk(wps->wps->registrar,
wps->peer_dev.mac_addr,
wps->p2p_dev_addr, psk, sizeof(psk));
}
#endif
return 0;
}
wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
(unsigned int) wps->wps->network_key_len);
wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
wpabuf_put_be16(msg, wps->wps->network_key_len);
wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
@@ -321,6 +355,11 @@ static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
{
#ifdef DEBUG_PRINT
const u8 *start, *end;
#endif
int ret;
if (wps->wps->ap_settings) {
wpa_printf(MSG_DEBUG, "WPS: * AP Settings (pre-configured)");
wpabuf_put_data(plain, wps->wps->ap_settings,
@@ -328,11 +367,23 @@ static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
return 0;
}
return wps_build_cred_ssid(wps, plain) ||
wpa_printf(MSG_DEBUG, "WPS: * AP Settings based on current configuration");
#ifdef DEBUG_PRINT
start = wpabuf_put(plain, 0);
#endif
ret = wps_build_cred_ssid(wps, plain) ||
wps_build_cred_mac_addr(wps, plain) ||
wps_build_cred_auth_type(wps, plain) ||
wps_build_cred_encr_type(wps, plain) ||
wps_build_cred_network_key(wps, plain);
#ifdef DEBUG_PRINT
end = wpabuf_put(plain, 0);
wpa_hexdump_key(MSG_DEBUG, "WPS: Plaintext AP Settings",
start, end - start);
#endif
return ret;
}
@@ -359,14 +410,15 @@ static struct wpabuf * wps_build_m7(struct wps_data *wps)
(wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) ||
wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(plain);
wpabuf_clear_free(plain);
wpabuf_free(msg);
return NULL;
}
wpabuf_free(plain);
wpabuf_clear_free(plain);
#ifdef CONFIG_WPS_REGISTRAR
if (wps->wps->ap && wps->wps->registrar) {
/*
* If the Registrar is only learning our current configuration,
@@ -376,6 +428,7 @@ static struct wpabuf * wps_build_m7(struct wps_data *wps)
wps_device_store(wps->wps->registrar, &wps->peer_dev,
wps->uuid_r);
}
#endif
wps->state = RECV_M8;
return msg;
@@ -396,7 +449,7 @@ static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
wps_build_msg_type(msg, WPS_WSC_DONE) ||
wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) ||
wps_build_wfa_ext(msg, 0, NULL, 0)) {
wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
wpabuf_free(msg);
return NULL;
}
@@ -404,7 +457,7 @@ static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
if (wps->wps->ap)
wps->state = RECV_ACK;
else {
wps_success_event(wps->wps);
wps_success_event(wps->wps, wps->peer_dev.mac_addr);
wps->state = WPS_FINISHED;
}
return msg;
@@ -525,18 +578,31 @@ static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
return -1;
}
if (wps->peer_pubkey_hash_set) {
u8 hash[WPS_HASH_LEN];
sha256_vector(1, &pk, &pk_len, hash);
if (os_memcmp_const(hash, wps->peer_pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
pk, pk_len);
wpa_hexdump(MSG_DEBUG, "WPS: Calculated public key "
"hash", hash, WPS_OOB_PUBKEY_HASH_LEN);
wpa_hexdump(MSG_DEBUG, "WPS: Expected public key hash",
wps->peer_pubkey_hash,
WPS_OOB_PUBKEY_HASH_LEN);
wps->config_error = WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
return -1;
}
}
wpabuf_free(wps->dh_pubkey_r);
wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
if (wps->dh_pubkey_r == NULL)
return -1;
wpa_printf(MSG_DEBUG, "process pubkey start\n");
if (wps_derive_keys(wps) < 0) {
if (wps_derive_keys(wps) < 0)
return -1;
}
wpa_printf(MSG_DEBUG, "process pubkey finish\n");
return 0;
}
@@ -593,13 +659,13 @@ static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
"not match with the pre-committed value");
wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
wps_pwd_auth_fail_event(wps->wps, 1, 1);
wps_pwd_auth_fail_event(wps->wps, 1, 1, wps->peer_dev.mac_addr);
return -1;
}
@@ -633,14 +699,13 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
"not match with the pre-committed value");
wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
wps_pwd_auth_fail_event(wps->wps, 1, 2);
wps_pwd_auth_fail_event(wps->wps, 1, 2, wps->peer_dev.mac_addr);
return -1;
}
@@ -652,7 +717,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
size_t cred_len, int cred_idx, int wps2)
size_t cred_len, int wps2)
{
struct wps_parse_attr *attr;
struct wpabuf msg;
@@ -695,7 +760,6 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
#endif /* CONFIG_WPS_STRICT */
}
#ifdef CONFIG_WPS2
if (!(wps->cred.encr_type &
(WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES))) {
if (wps->cred.encr_type & WPS_ENCR_WEP) {
@@ -711,9 +775,6 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
ret = -1;
goto _out;
}
#endif /* CONFIG_WPS2 */
wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len, cred_idx);
wps_key_save((char *)wps->cred.key, wps->cred.key_len, cred_idx);
if (wps->wps->cred_cb) {
wps->cred.cred_attr = cred - 4;
@@ -732,7 +793,7 @@ _out:
static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
size_t cred_len[], size_t num_cred, int wps2)
u16 cred_len[], unsigned int num_cred, int wps2)
{
size_t i;
int ok = 0;
@@ -748,12 +809,11 @@ static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
for (i = 0; i < num_cred; i++) {
int res;
res = wps_process_cred_e(wps, cred[i], cred_len[i], i, wps2);
res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
if (res == 0)
ok++;
else if (res == -2) {
else if (res == -2)
wpa_printf(MSG_DEBUG, "WPS: WEP credential skipped");
}
else
return -1;
}
@@ -817,7 +877,6 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
#endif /* CONFIG_WPS_STRICT */
}
#ifdef CONFIG_WPS2
if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
{
if (cred->encr_type & WPS_ENCR_WEP) {
@@ -833,7 +892,6 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
ret = -1;
goto _out;
}
#endif /* CONFIG_WPS2 */
#ifdef CONFIG_WPS_STRICT
if (wps2) {
@@ -851,7 +909,6 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
}
#endif /* CONFIG_WPS_STRICT */
#ifdef CONFIG_WPS2
if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
{
wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
@@ -865,7 +922,6 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
"WPAPSK+WPA2PSK");
cred->auth_type |= WPS_AUTH_WPA2PSK;
}
#endif /* CONFIG_WPS2 */
if (wps->wps->cred_cb) {
cred->cred_attr = wpabuf_head(attrs);
@@ -881,6 +937,63 @@ _out:
}
static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id)
{
u16 id;
if (dev_pw_id == NULL) {
wpa_printf(MSG_DEBUG, "WPS: Device Password ID");
return -1;
}
id = WPA_GET_BE16(dev_pw_id);
if (wps->dev_pw_id == id) {
wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id);
return 0;
}
#ifdef CONFIG_P2P
if ((id == DEV_PW_DEFAULT &&
wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) ||
(id == DEV_PW_REGISTRAR_SPECIFIED &&
wps->dev_pw_id == DEV_PW_DEFAULT)) {
/*
* Common P2P use cases indicate whether the PIN is from the
* client or GO using Device Password Id in M1/M2 in a way that
* does not look fully compliant with WSC specification. Anyway,
* this is deployed and needs to be allowed, so ignore changes
* between Registrar-Specified and Default PIN.
*/
wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID "
"change");
return 0;
}
#endif /* CONFIG_P2P */
wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
"ID from %u to %u", wps->dev_pw_id, id);
if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) {
wpa_printf(MSG_DEBUG,
"WPS: Workaround - ignore PBC-to-PIN change");
return 0;
}
if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
bin_clear_free(wps->dev_password, wps->dev_password_len);
wps->dev_pw_id = wps->alt_dev_pw_id;
wps->dev_password = wps->alt_dev_password;
wps->dev_password_len = wps->alt_dev_password_len;
wps->alt_dev_password = NULL;
wps->alt_dev_password_len = 0;
return 0;
}
return -1;
}
static enum wps_process_res wps_process_m2(struct wps_data *wps,
const struct wpabuf *msg,
struct wps_parse_attr *attr)
@@ -896,7 +1009,8 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps,
if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
wps_process_uuid_r(wps, attr->uuid_r)) {
wps_process_uuid_r(wps, attr->uuid_r) ||
wps_process_dev_pw_id(wps, attr->dev_password_id)) {
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
@@ -924,6 +1038,38 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps,
return WPS_CONTINUE;
}
#ifdef CONFIG_WPS_NFC
if (wps->peer_pubkey_hash_set) {
struct wpabuf *decrypted;
struct wps_parse_attr eattr;
decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
attr->encr_settings_len);
if (decrypted == NULL) {
wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt "
"Encrypted Settings attribute");
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted "
"Settings attribute");
if (wps_parse_msg(decrypted, &eattr) < 0 ||
wps_process_key_wrap_auth(wps, decrypted,
eattr.key_wrap_auth) ||
wps_process_creds(wps, eattr.cred, eattr.cred_len,
eattr.num_cred, attr->version2 != NULL)) {
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
wpabuf_clear_free(decrypted);
wps->state = WPS_MSG_DONE;
return WPS_CONTINUE;
}
#endif /* CONFIG_WPS_NFC */
wps->state = SEND_M3;
return WPS_CONTINUE;
}
@@ -1029,7 +1175,7 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps,
}
if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
res = WPS_CONTINUE;
goto _out;
@@ -1045,7 +1191,7 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps,
res = WPS_CONTINUE;
goto _out;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_M5;
res = WPS_CONTINUE;
@@ -1099,7 +1245,7 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps,
}
if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
res = WPS_CONTINUE;
goto _out;
@@ -1115,7 +1261,7 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps,
res = WPS_CONTINUE;
goto _out;
}
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
if (wps->wps->ap)
wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
@@ -1188,7 +1334,7 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps,
if (wps_validate_m8_encr(decrypted, wps->wps->ap,
attr->version2 != NULL) < 0) {
wpabuf_free(decrypted);
wpabuf_clear_free(decrypted);
wps->state = SEND_WSC_NACK;
res = WPS_CONTINUE;
goto _out;
@@ -1232,11 +1378,6 @@ static enum wps_process_res wps_process_wsc_start(struct wps_data *wps,
return ret;
}
#define WPS_IGNORE_STATE(wps_st) do {\
if (wps->state <= RECV_M8 && ((wps_st) == wps->state - 1 || (wps_st) == wps->state - 2)) { \
return WPS_IGNORE;\
}\
} while (0)
static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
const struct wpabuf *msg)
@@ -1273,7 +1414,6 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
switch (*attr->msg_type) {
case WPS_M2:
WPS_IGNORE_STATE(RECV_M2);
if (wps_validate_m2(msg) < 0) {
ret = WPS_FAILURE;
goto _out;
@@ -1288,7 +1428,6 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
ret = wps_process_m2d(wps, attr);
break;
case WPS_M4:
WPS_IGNORE_STATE(RECV_M4);
if (wps_validate_m4(msg) < 0) {
ret = WPS_FAILURE;
goto _out;
@@ -1296,10 +1435,10 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
ret = wps_process_m4(wps, msg, attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M4, wps->config_error,
wps->error_indication);
wps->error_indication,
wps->peer_dev.mac_addr);
break;
case WPS_M6:
WPS_IGNORE_STATE(RECV_M6);
if (wps_validate_m6(msg) < 0) {
ret = WPS_FAILURE;
goto _out;
@@ -1307,10 +1446,10 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
ret = wps_process_m6(wps, msg, attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M6, wps->config_error,
wps->error_indication);
wps->error_indication,
wps->peer_dev.mac_addr);
break;
case WPS_M8:
WPS_IGNORE_STATE(RECV_M8);
if (wps_validate_m8(msg) < 0) {
ret = WPS_FAILURE;
goto _out;
@@ -1318,7 +1457,8 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
ret = wps_process_m8(wps, msg, attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
wps_fail_event(wps->wps, WPS_M8, wps->config_error,
wps->error_indication);
wps->error_indication,
wps->peer_dev.mac_addr);
break;
default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@@ -1399,7 +1539,7 @@ static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
if (wps->state == RECV_ACK && wps->wps->ap) {
wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
"completed successfully");
wps_success_event(wps->wps);
wps_success_event(wps->wps, wps->peer_dev.mac_addr);
wps->state = WPS_FINISHED;
res = WPS_DONE;
goto _out;
@@ -1484,15 +1624,15 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
switch (wps->state) {
case RECV_M4:
wps_fail_event(wps->wps, WPS_M3, config_error,
wps->error_indication);
wps->error_indication, wps->peer_dev.mac_addr);
break;
case RECV_M6:
wps_fail_event(wps->wps, WPS_M5, config_error,
wps->error_indication);
wps->error_indication, wps->peer_dev.mac_addr);
break;
case RECV_M8:
wps_fail_event(wps->wps, WPS_M7, config_error,
wps->error_indication);
wps->error_indication, wps->peer_dev.mac_addr);
break;
default:
break;

View File

@@ -11,8 +11,6 @@
#include "wps.h"
#include "wps_attr_parse.h"
#include "esp_wps.h"
#include "esp_wifi_crypto_types.h"
#ifdef CONFIG_WPS_NFC
struct wps_nfc_pw_token;
@@ -74,6 +72,12 @@ struct wps_data {
size_t dev_password_len;
u16 dev_pw_id;
int pbc;
u8 *alt_dev_password;
size_t alt_dev_password_len;
u16 alt_dev_pw_id;
u8 peer_pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
int peer_pubkey_hash_set;
/**
* request_type - Request Type attribute from (Re)AssocReq
@@ -120,38 +124,36 @@ struct wps_data {
u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
* 00:00:00:00:00:00 if not a P2p client */
int pbc_in_m1;
#ifdef CONFIG_WPS_NFC
struct wps_nfc_pw_token *nfc_pw_token;
#endif
int multi_ap_backhaul_sta;
};
/* wps_common.c */
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
const char *label, u8 *res, size_t res_len);
int wps_derive_keys(struct wps_data *wps);
void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
int wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
size_t dev_passwd_len);
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
size_t encr_len);
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
u16 config_error, u16 error_indication);
void wps_success_event(struct wps_context *wps);
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
u16 config_error, u16 error_indication, const u8 *mac_addr);
void wps_success_event(struct wps_context *wps, const u8 *mac_addr);
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part,
const u8 *mac_addr);
void wps_pbc_overlap_event(struct wps_context *wps);
void wps_pbc_timeout_event(struct wps_context *wps);
void wps_pbc_active_event(struct wps_context *wps);
void wps_pbc_disable_event(struct wps_context *wps);
struct wpabuf * wps_build_wsc_ack(struct wps_data *wps);
struct wpabuf * wps_build_wsc_nack(struct wps_data *wps);
typedef enum wps_calc_key_mode {
WPS_CALC_KEY_NORMAL = 0,
WPS_CALC_KEY_NO_CALC,
WPS_CALC_KEY_PRE_CALC,
WPS_CALC_KEY_MAX,
} wps_key_mode_t;
/* wps_attr_build.c */
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_t mode);
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type);
int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type);
int wps_build_config_methods(struct wpabuf *msg, u16 methods);
@@ -164,7 +166,8 @@ int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
struct wpabuf *plain);
int wps_build_version(struct wpabuf *msg);
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
const u8 *auth_macs, size_t auth_macs_count);
const u8 *auth_macs, size_t auth_macs_count,
u8 multi_ap_subelem);
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
@@ -176,6 +179,9 @@ int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id,
const struct wpabuf *pubkey, const u8 *dev_pw,
size_t dev_pw_len);
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data);
int wps_build_mac_addr(struct wpabuf *msg, const u8 *addr);
int wps_build_rf_bands_attr(struct wpabuf *msg, u8 rf_bands);
int wps_build_ap_channel(struct wpabuf *msg, u16 ap_channel);
/* wps_attr_process.c */
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
@@ -203,7 +209,8 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
int wps_build_cred(struct wps_data *wps, struct wpabuf *msg);
int wps_device_store(struct wps_registrar *reg,
struct wps_device_data *dev, const u8 *uuid);
void wps_registrar_selected_registrar_changed(struct wps_registrar *reg);
void wps_registrar_selected_registrar_changed(struct wps_registrar *reg,
u16 dev_pw_id);
const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count);
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
const u8 *addr, const u8 *uuid_e);
@@ -212,5 +219,7 @@ int wps_registrar_pbc_overlap(struct wps_registrar *reg,
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
struct wps_nfc_pw_token *token);
#endif
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 */

File diff suppressed because it is too large Load Diff

View File

@@ -5,15 +5,14 @@
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "wps/wps_i.h"
#include "wps/wps.h"
#include "wps_i.h"
#include "wps.h"
#ifdef CONFIG_WPS_STRICT
#ifndef WPS_STRICT_ALL
#define WPS_STRICT_WPS2
#endif /* WPS_STRICT_ALL */
@@ -98,11 +97,23 @@ static int wps_validate_response_type(const u8 *response_type, int mandatory)
static int valid_config_methods(u16 val, int wps2)
{
if (wps2) {
if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
"Display flag without old Display flag "
"set");
return 0;
}
if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
"without Physical/Virtual Display flag");
return 0;
}
if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
"PushButton flag without old PushButton "
"flag set");
return 0;
}
if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
"without Physical/Virtual PushButton flag");
@@ -213,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);
@@ -256,7 +269,7 @@ static int wps_validate_config_error(const u8 *config_error, int mandatory)
return 0;
}
val = WPA_GET_BE16(config_error);
if (val > 18) {
if (val > 20) {
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
"attribute value 0x%04x", val);
return -1;
@@ -279,7 +292,7 @@ static int wps_validate_dev_password_id(const u8 *dev_password_id,
return 0;
}
val = WPA_GET_BE16(dev_password_id);
if (val >= 0x0006 && val <= 0x000f) {
if (val >= 0x0008 && val <= 0x000f) {
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
"attribute value 0x%04x", val);
return -1;
@@ -1059,7 +1072,7 @@ _out:
}
static int wps_validate_credential(const u8 *cred[], size_t len[], size_t num,
static int wps_validate_credential(const u8 *cred[], u16 len[], size_t num,
int mandatory)
{
size_t i;
@@ -2363,4 +2376,3 @@ _out:
return ret;
}
#endif

View File

@@ -1657,13 +1657,10 @@ components/wifi_provisioning/src/wifi_config.c
components/wifi_provisioning/src/wifi_provisioning_priv.h
components/wifi_provisioning/src/wifi_scan.c
components/wpa_supplicant/esp_supplicant/include/esp_rrm.h
components/wpa_supplicant/esp_supplicant/include/esp_wps.h
components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h
components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c
components/wpa_supplicant/esp_supplicant/src/esp_wpa3_i.h
components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h
components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c
components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h
components/wpa_supplicant/include/utils/wpa_debug.h
components/wpa_supplicant/include/utils/wpabuf.h
components/wpa_supplicant/port/include/byteswap.h