forked from espressif/esp-idf
Merge branch 'feature/wps_code_updation' into 'master'
wpa_supplicant: wps code cleanup See merge request espressif/esp-idf!16577
This commit is contained in:
@@ -22,6 +22,7 @@ set(srcs "port/os_xtensa.c"
|
|||||||
"src/crypto/sha384-prf.c"
|
"src/crypto/sha384-prf.c"
|
||||||
"src/crypto/md4-internal.c"
|
"src/crypto/md4-internal.c"
|
||||||
"src/crypto/sha1-tprf.c"
|
"src/crypto/sha1-tprf.c"
|
||||||
|
"src/eap_common/eap_wsc_common.c"
|
||||||
"src/eap_peer/chap.c"
|
"src/eap_peer/chap.c"
|
||||||
"src/eap_peer/eap.c"
|
"src/eap_peer/eap.c"
|
||||||
"src/eap_peer/eap_common.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_attr_process.c"
|
||||||
"src/wps/wps_common.c"
|
"src/wps/wps_common.c"
|
||||||
"src/wps/wps_dev_attr.c"
|
"src/wps/wps_dev_attr.c"
|
||||||
"src/wps/wps_enrollee.c"
|
"src/wps/wps_enrollee.c")
|
||||||
"src/wps/wps_registrar.c"
|
# "src/wps/wps_registrar.c")
|
||||||
"src/wps/wps_validate.c")
|
|
||||||
|
|
||||||
set(esp_srcs "esp_supplicant/src/esp_wpa2.c"
|
set(esp_srcs "esp_supplicant/src/esp_wpa2.c"
|
||||||
"esp_supplicant/src/esp_wpa_main.c"
|
"esp_supplicant/src/esp_wpa_main.c"
|
||||||
@@ -66,7 +66,7 @@ if(CONFIG_ESP_WIFI_SOFTAP_SUPPORT)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_WPA_MBEDTLS_CRYPTO)
|
if(CONFIG_WPA_MBEDTLS_CRYPTO)
|
||||||
set(tls_src "src/crypto/tls_mbedtls.c")
|
set(tls_src "esp_supplicant/src/crypto/tls_mbedtls.c")
|
||||||
else()
|
else()
|
||||||
set(tls_src
|
set(tls_src
|
||||||
"src/tls/asn1.c"
|
"src/tls/asn1.c"
|
||||||
@@ -91,9 +91,9 @@ endif()
|
|||||||
|
|
||||||
if(CONFIG_WPA_MBEDTLS_CRYPTO)
|
if(CONFIG_WPA_MBEDTLS_CRYPTO)
|
||||||
set(crypto_src
|
set(crypto_src
|
||||||
"src/crypto/crypto_mbedtls.c"
|
"esp_supplicant/src/crypto/crypto_mbedtls.c"
|
||||||
"src/crypto/crypto_mbedtls-bignum.c"
|
"esp_supplicant/src/crypto/crypto_mbedtls-bignum.c"
|
||||||
"src/crypto/crypto_mbedtls-ec.c")
|
"esp_supplicant/src/crypto/crypto_mbedtls-ec.c")
|
||||||
# Add internal RC4 if RC4 is disabled in mbedtls
|
# Add internal RC4 if RC4 is disabled in mbedtls
|
||||||
if(CONFIG_MBEDTLS_RC4_DISABLED)
|
if(CONFIG_MBEDTLS_RC4_DISABLED)
|
||||||
set(crypto_src ${crypto_src} "src/crypto/rc4.c")
|
set(crypto_src ${crypto_src} "src/crypto/rc4.c")
|
||||||
@@ -133,7 +133,6 @@ else()
|
|||||||
"src/crypto/crypto_internal-cipher.c"
|
"src/crypto/crypto_internal-cipher.c"
|
||||||
"src/crypto/crypto_internal-modexp.c"
|
"src/crypto/crypto_internal-modexp.c"
|
||||||
"src/crypto/crypto_internal-rsa.c"
|
"src/crypto/crypto_internal-rsa.c"
|
||||||
"src/crypto/crypto_mbedtls-rsa.c"
|
|
||||||
"src/crypto/crypto_internal.c"
|
"src/crypto/crypto_internal.c"
|
||||||
"src/crypto/des-internal.c"
|
"src/crypto/des-internal.c"
|
||||||
"src/crypto/md4-internal.c"
|
"src/crypto/md4-internal.c"
|
||||||
@@ -180,7 +179,7 @@ endif()
|
|||||||
idf_component_register(SRCS "${srcs}" ${esp_srcs} "${tls_src}" "${roaming_src}"
|
idf_component_register(SRCS "${srcs}" ${esp_srcs} "${tls_src}" "${roaming_src}"
|
||||||
"${crypto_src}" "${mbo_src}" "${dpp_src}"
|
"${crypto_src}" "${mbo_src}" "${dpp_src}"
|
||||||
INCLUDE_DIRS include port/include esp_supplicant/include
|
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)
|
PRIV_REQUIRES mbedtls esp_timer)
|
||||||
|
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing -Wno-write-strings -Werror)
|
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing -Wno-write-strings -Werror)
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2019-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.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef __ESP_WPS_H__
|
#ifndef __ESP_WPS_H__
|
||||||
#define __ESP_WPS_H__
|
#define __ESP_WPS_H__
|
||||||
|
@@ -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
|
||||||
*
|
*
|
||||||
*
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
@@ -40,6 +40,7 @@
|
|||||||
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
||||||
#include "esp_crt_bundle.h"
|
#include "esp_crt_bundle.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "esp_wpas_glue.h"
|
||||||
|
|
||||||
#define WPA2_VERSION "v2.0"
|
#define WPA2_VERSION "v2.0"
|
||||||
|
|
||||||
@@ -297,74 +298,6 @@ int wpa2_post(uint32_t sig, uint32_t par)
|
|||||||
|
|
||||||
#endif /* USE_WPA2_TASK */
|
#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)
|
int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
|
||||||
{
|
{
|
||||||
size_t outlen;
|
size_t outlen;
|
||||||
@@ -379,15 +312,15 @@ int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
|
|||||||
return WPA_ERR_INVALID_BSSID;
|
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),
|
wpabuf_head_u8(resp), wpabuf_len(resp),
|
||||||
&outlen, NULL);
|
&outlen, NULL);
|
||||||
if (!outbuf) {
|
if (!outbuf) {
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
|
ret = wpa_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
|
||||||
wpa2_sm_free_eapol(outbuf);
|
wpa_free_eapol(outbuf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
@@ -718,14 +651,14 @@ static int wpa2_start_eapol_internal(void)
|
|||||||
return WPA_ERR_INVALID_BSSID;
|
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) {
|
if (!buf) {
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
|
wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
|
||||||
wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
wpa_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
|
||||||
wpa2_sm_free_eapol(buf);
|
wpa_free_eapol(buf);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2019-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.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// 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.
|
|
||||||
|
|
||||||
#ifdef ESP_SUPPLICANT
|
#ifdef ESP_SUPPLICANT
|
||||||
|
|
||||||
@@ -19,10 +11,12 @@
|
|||||||
#include "common/eapol_common.h"
|
#include "common/eapol_common.h"
|
||||||
#include "rsn_supp/wpa.h"
|
#include "rsn_supp/wpa.h"
|
||||||
#include "rsn_supp/pmksa_cache.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,
|
const void *data, u16 data_len,
|
||||||
size_t *msg_len, void **data_pos)
|
size_t *msg_len, void **data_pos)
|
||||||
{
|
{
|
||||||
void *buffer;
|
void *buffer;
|
||||||
struct ieee802_1x_hdr *hdr;
|
struct ieee802_1x_hdr *hdr;
|
||||||
@@ -38,7 +32,7 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
|||||||
/* XXX: reserve l2_ethhdr is enough */
|
/* XXX: reserve l2_ethhdr is enough */
|
||||||
hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
|
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->type = type;
|
||||||
hdr->length = host_to_be16(data_len);
|
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;
|
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);
|
buffer = buffer - sizeof(struct l2_ethhdr);
|
||||||
os_free(buffer);
|
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)
|
void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2019-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.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// 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.
|
|
||||||
|
|
||||||
#ifndef WPAS_GLUE_H
|
#ifndef WPAS_GLUE_H
|
||||||
#define 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);
|
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 */
|
#endif /* WPAS_GLUE_H */
|
||||||
|
@@ -26,6 +26,10 @@
|
|||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_private/wifi.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 {\
|
#define API_MUTEX_TAKE() do {\
|
||||||
if (!s_wps_api_lock) {\
|
if (!s_wps_api_lock) {\
|
||||||
@@ -281,33 +285,26 @@ int wps_post(uint32_t sig, uint32_t par)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* wps_sm_ether_send - Send Ethernet frame
|
||||||
* @wpa_s: Pointer to wpa_supplicant data
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
* @dest: Destination MAC address
|
|
||||||
* @proto: Ethertype in host byte order
|
* @proto: Ethertype in host byte order
|
||||||
* @buf: Frame payload starting from IEEE 802.1X header
|
* @buf: Frame payload starting from IEEE 802.1X header
|
||||||
* @len: Frame payload length
|
* @len: Frame payload length
|
||||||
* Returns: >=0 on success, <0 on failure
|
* 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)
|
const u8 *data, size_t data_len)
|
||||||
{
|
{
|
||||||
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
|
u8 bssid[ETH_ALEN];
|
||||||
struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
|
int ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
||||||
|
|
||||||
os_memcpy(eth->h_dest, dest, ETH_ALEN);
|
if (ret != 0) {
|
||||||
os_memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
|
wpa_printf(MSG_ERROR, "bssid is empty!");
|
||||||
eth->h_proto = host_to_be16(proto);
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
|
return wpa_ether_send(sm, bssid, proto, data, data_len);
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -315,189 +312,13 @@ u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
|
|||||||
const void *data, u16 data_len,
|
const void *data, u16 data_len,
|
||||||
size_t *msg_len, void **data_pos)
|
size_t *msg_len, void **data_pos)
|
||||||
{
|
{
|
||||||
void *buffer;
|
return wpa_alloc_eapol(sm, type, data, data_len, msg_len, data_pos);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wps_sm_free_eapol(u8 *buffer)
|
void wps_sm_free_eapol(u8 *buffer)
|
||||||
{
|
{
|
||||||
if (buffer != NULL) {
|
return wpa_free_eapol(buffer);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -506,20 +327,17 @@ wps_build_ic_appie_wps_pr(void)
|
|||||||
struct wpabuf *extra_ie = NULL;
|
struct wpabuf *extra_ie = NULL;
|
||||||
struct wpabuf *wps_ie;
|
struct wpabuf *wps_ie;
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
|
u16 pw_id;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "wps build: wps pr");
|
wpa_printf(MSG_DEBUG, "wps build: wps pr");
|
||||||
|
|
||||||
if (wps_get_type() == WPS_TYPE_PBC) {
|
if (wps_get_type() == WPS_TYPE_PBC) {
|
||||||
wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_PUSHBUTTON,
|
pw_id = DEV_PW_PUSHBUTTON;
|
||||||
sm->dev,
|
|
||||||
sm->uuid, WPS_REQ_ENROLLEE,
|
|
||||||
0, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_DEFAULT,
|
pw_id = DEV_PW_DEFAULT;
|
||||||
sm->dev,
|
|
||||||
sm->uuid, WPS_REQ_ENROLLEE,
|
|
||||||
0, NULL);
|
|
||||||
}
|
}
|
||||||
|
wps_ie = wps_build_probe_req_ie(pw_id, sm->dev, sm->uuid,
|
||||||
|
WPS_REQ_ENROLLEE, 0, NULL);
|
||||||
|
|
||||||
if (!wps_ie) {
|
if (!wps_ie) {
|
||||||
return;
|
return;
|
||||||
@@ -540,7 +358,7 @@ wps_build_ic_appie_wps_pr(void)
|
|||||||
static void
|
static void
|
||||||
wps_build_ic_appie_wps_ar(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");
|
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;
|
struct wps_sm *sm = gWpsSm;
|
||||||
wifi_mode_t op_mode = 0;
|
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) {
|
if (!sm->is_wps_scan || !scan->bssid) {
|
||||||
return false;
|
return false;
|
||||||
@@ -574,22 +385,26 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
|
|||||||
return false;
|
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");
|
wpa_printf(MSG_INFO, "WEP not suppported in WPS");
|
||||||
return false;
|
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 */
|
/* We have selected candidate for this scan */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_wifi_get_mode(&op_mode);
|
if (scan->wps) {
|
||||||
if ((op_mode == WIFI_MODE_STA
|
|
||||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
|
||||||
|| op_mode == WIFI_MODE_APSTA
|
|
||||||
#endif
|
|
||||||
) && scan->wps) {
|
|
||||||
bool ap_found = false;
|
bool ap_found = false;
|
||||||
struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
|
struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
|
||||||
int count;
|
int count;
|
||||||
@@ -601,11 +416,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
|
|||||||
sm->discard_ap_cnt = 0;
|
sm->discard_ap_cnt = 0;
|
||||||
ap_found = true;
|
ap_found = true;
|
||||||
}
|
}
|
||||||
if ((op_mode == WIFI_MODE_STA
|
if (wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
|
||||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
|
||||||
|| op_mode == WIFI_MODE_APSTA
|
|
||||||
#endif
|
|
||||||
) && wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
|
|
||||||
/* AP is in discard list? */
|
/* AP is in discard list? */
|
||||||
for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
|
for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
|
||||||
if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sm->wps_pin_war = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ap_found || sm->wps_pin_war) {
|
if (ap_found || sm->ignore_sel_reg) {
|
||||||
wpabuf_free(buf);
|
wpabuf_free(buf);
|
||||||
esp_wifi_enable_sta_privacy_internal();
|
esp_wifi_enable_sta_privacy_internal();
|
||||||
os_memset(sm->config.ssid, 0, sizeof(sm->config.ssid));
|
os_memset(sm->ssid[0], 0, SSID_MAX_LEN);
|
||||||
strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
|
strncpy((char *)sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]);
|
||||||
if (scan->bssid && memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0) {
|
sm->ssid_len[0] = scan->ssid[1];
|
||||||
printf("sm BSSid: "MACSTR " scan BSSID " MACSTR "\n", MAC2STR(sm->config.bssid), MAC2STR(scan->bssid));
|
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++;
|
sm->discover_ssid_cnt++;
|
||||||
os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
|
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;
|
sm->channel = scan->chan;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -643,7 +453,6 @@ int wps_send_eap_identity_rsp(u8 id)
|
|||||||
{
|
{
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
struct wpabuf *eap_buf = NULL;
|
struct wpabuf *eap_buf = NULL;
|
||||||
u8 bssid[6];
|
|
||||||
u8 *buf = NULL;
|
u8 *buf = NULL;
|
||||||
int len;
|
int len;
|
||||||
int ret = ESP_OK;
|
int ret = ESP_OK;
|
||||||
@@ -656,12 +465,6 @@ int wps_send_eap_identity_rsp(u8 id)
|
|||||||
goto _err;
|
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);
|
wpabuf_put_data(eap_buf, sm->identity, sm->identity_len);
|
||||||
|
|
||||||
@@ -671,7 +474,7 @@ int wps_send_eap_identity_rsp(u8 id)
|
|||||||
goto _err;
|
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) {
|
if (ret) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _err;
|
goto _err;
|
||||||
@@ -687,11 +490,9 @@ int wps_send_frag_ack(u8 id)
|
|||||||
{
|
{
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
struct wpabuf *eap_buf = NULL;
|
struct wpabuf *eap_buf = NULL;
|
||||||
u8 bssid[6];
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int len;
|
int len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
enum wsc_op_code opcode = WSC_FRAG_ACK;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "send frag ack id:%d", id);
|
wpa_printf(MSG_DEBUG, "send frag ack id:%d", id);
|
||||||
|
|
||||||
@@ -699,28 +500,19 @@ int wps_send_frag_ack(u8 id)
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
eap_buf = eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE);
|
||||||
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);
|
|
||||||
if (!eap_buf) {
|
if (!eap_buf) {
|
||||||
ret = ESP_ERR_NO_MEM;
|
ret = ESP_ERR_NO_MEM;
|
||||||
goto _err;
|
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);
|
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) {
|
if (!buf) {
|
||||||
ret = ESP_ERR_NO_MEM;
|
ret = ESP_ERR_NO_MEM;
|
||||||
goto _err;
|
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);
|
wps_sm_free_eapol(buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = ESP_ERR_NO_MEM;
|
ret = ESP_ERR_NO_MEM;
|
||||||
@@ -859,7 +651,6 @@ int wps_send_wps_mX_rsp(u8 id)
|
|||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
struct wpabuf *eap_buf = NULL;
|
struct wpabuf *eap_buf = NULL;
|
||||||
struct wpabuf *wps_buf = NULL;
|
struct wpabuf *wps_buf = NULL;
|
||||||
u8 bssid[6];
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int len;
|
int len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -871,13 +662,7 @@ int wps_send_wps_mX_rsp(u8 id)
|
|||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = esp_wifi_get_assoc_bssid_internal(bssid);
|
wps_buf = wps_enrollee_get_msg(sm->wps, &opcode);
|
||||||
if (ret != 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "bssid is empty!");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
wps_buf = (struct wpabuf *)wps_enrollee_get_msg(sm->wps, &opcode);
|
|
||||||
if (!wps_buf) {
|
if (!wps_buf) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _err;
|
goto _err;
|
||||||
@@ -902,7 +687,7 @@ int wps_send_wps_mX_rsp(u8 id)
|
|||||||
goto _err;
|
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);
|
wps_sm_free_eapol(buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
@@ -919,16 +704,8 @@ _err:
|
|||||||
int wps_tx_start(void)
|
int wps_tx_start(void)
|
||||||
{
|
{
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
u8 bssid[6];
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int len;
|
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) {
|
if (!sm) {
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
@@ -940,7 +717,7 @@ int wps_tx_start(void)
|
|||||||
return ESP_ERR_NO_MEM;
|
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);
|
wps_sm_free_eapol(buf);
|
||||||
|
|
||||||
ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0);
|
ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0);
|
||||||
@@ -958,6 +735,30 @@ int wps_start_pending(void)
|
|||||||
return wps_tx_start();
|
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)
|
int wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)
|
||||||
{
|
{
|
||||||
struct wps_sm *sm = gWpsSm;
|
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);
|
wps_set_status(WPS_STATUS_DISABLE);
|
||||||
sm->scan_cnt = 0;
|
wps_sm_init(sm);
|
||||||
sm->discover_ssid_cnt = 0;
|
|
||||||
sm->wps->state = SEND_M1;
|
sm->wps->state = SEND_M1;
|
||||||
os_bzero(sm->bssid, ETH_ALEN);
|
wps_stop_connection_timers(sm);
|
||||||
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);
|
|
||||||
|
|
||||||
esp_wifi_disconnect();
|
esp_wifi_disconnect();
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Write wps_fail_information");
|
wpa_printf(MSG_DEBUG, "Write wps_fail_information");
|
||||||
@@ -999,23 +791,17 @@ int wps_finish(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sm->wps->state == WPS_FINISHED) {
|
if (sm->wps->state == WPS_FINISHED) {
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "wps finished------>");
|
wpa_printf(MSG_DEBUG, "wps finished------>");
|
||||||
wps_set_status(WPS_STATUS_SUCCESS);
|
wps_set_status(WPS_STATUS_SUCCESS);
|
||||||
esp_wifi_disarm_sta_connection_timer_internal();
|
wps_stop_connection_timers(sm);
|
||||||
ets_timer_disarm(&sm->wps_timeout_timer);
|
|
||||||
ets_timer_disarm(&sm->wps_msg_timeout_timer);
|
|
||||||
|
|
||||||
if (sm->ap_cred_cnt == 1) {
|
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) {
|
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;
|
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.ssid, sm->ssid[0], sm->ssid_len[0]);
|
||||||
os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
|
os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
|
||||||
os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
|
os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
|
||||||
@@ -1023,20 +809,19 @@ int wps_finish(void)
|
|||||||
esp_wifi_set_config(0, config);
|
esp_wifi_set_config(0, config);
|
||||||
|
|
||||||
os_free(config);
|
os_free(config);
|
||||||
config = NULL;
|
|
||||||
}
|
}
|
||||||
ets_timer_disarm(&sm->wps_success_cb_timer);
|
ets_timer_disarm(&sm->wps_success_cb_timer);
|
||||||
ets_timer_arm(&sm->wps_success_cb_timer, 1000, 0);
|
ets_timer_arm(&sm->wps_success_cb_timer, 1000, 0);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_ERROR, "wps failed-----> wps_pin_war=%d", sm->wps_pin_war);
|
wpa_printf(MSG_ERROR, "wps failed-----> ignore_sel_reg=%d", sm->ignore_sel_reg);
|
||||||
if (sm->wps_pin_war) {
|
if (sm->ignore_sel_reg) {
|
||||||
sm->discover_ssid_cnt = 0;
|
sm->discover_ssid_cnt = 0;
|
||||||
esp_wifi_disconnect();
|
esp_wifi_disconnect();
|
||||||
os_bzero(sm->ssid, sizeof(sm->ssid));
|
os_bzero(sm->ssid, sizeof(sm->ssid));
|
||||||
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
||||||
wps_add_discard_ap(sm->config.bssid);
|
wps_add_discard_ap(sm->bssid);
|
||||||
} else {
|
} else {
|
||||||
ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
|
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;
|
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);
|
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
|
#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) {
|
if (!param) {
|
||||||
return ESP_ERR_NO_MEM;
|
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) {
|
if (!param->buf) {
|
||||||
os_free(param);
|
os_free(param);
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
@@ -1281,8 +1066,7 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (ret != 0 && sm->wps_pin_war) {
|
if (ret != 0 && sm->ignore_sel_reg) {
|
||||||
sm->wps_pin_war = false;
|
|
||||||
wifi_wps_scan();
|
wifi_wps_scan();
|
||||||
} else if ((ret != 0 || res == WPS_FAILURE)) {
|
} else if ((ret != 0 || res == WPS_FAILURE)) {
|
||||||
wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
|
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) {
|
if (!dev->manufacturer) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
sprintf(dev->manufacturer, s_factory_info->manufacturer);
|
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) {
|
if (!dev->model_name) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
sprintf(dev->model_name, s_factory_info->model_name);
|
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) {
|
if (!dev->model_number) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
sprintf(dev->model_number, s_factory_info->model_number);
|
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) {
|
if (!dev->device_name) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
sprintf(dev->device_name, s_factory_info->device_name);
|
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) {
|
if (!dev->serial_number) {
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _out;
|
goto _out;
|
||||||
@@ -1424,30 +1208,7 @@ int wps_dev_init(void)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
if (!dev) {
|
wps_dev_deinit(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1524,17 +1285,16 @@ wifi_station_wps_msg_timeout_internal(void)
|
|||||||
return;
|
return;
|
||||||
} else if (sm->wps->state == RECV_M2) {
|
} else if (sm->wps->state == RECV_M2) {
|
||||||
wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
|
wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
|
||||||
wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>");
|
if (!sm->ignore_sel_reg) {
|
||||||
if (!sm->wps_pin_war) {
|
|
||||||
wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
|
wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sm->wps_pin_war) {
|
if (sm->ignore_sel_reg) {
|
||||||
esp_wifi_disconnect();
|
esp_wifi_disconnect();
|
||||||
wps_add_discard_ap(sm->config.bssid);
|
wps_add_discard_ap(sm->bssid);
|
||||||
sm->wps_pin_war = false;
|
|
||||||
os_bzero(sm->ssid, sizeof(sm->ssid));
|
os_bzero(sm->ssid, sizeof(sm->ssid));
|
||||||
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
|
||||||
|
os_bzero(sm->bssid, ETH_ALEN);
|
||||||
sm->discover_ssid_cnt = 0;
|
sm->discover_ssid_cnt = 0;
|
||||||
wifi_wps_scan();
|
wifi_wps_scan();
|
||||||
}
|
}
|
||||||
@@ -1557,7 +1317,7 @@ void wifi_station_wps_success_internal(void)
|
|||||||
int i;
|
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.
|
* the config. This is for backward compatibility.
|
||||||
*/
|
*/
|
||||||
if (sm->ap_cred_cnt > 1) {
|
if (sm->ap_cred_cnt > 1) {
|
||||||
@@ -1600,12 +1360,35 @@ void wifi_station_wps_eapol_start_handle(void)
|
|||||||
#endif
|
#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
|
int
|
||||||
wifi_station_wps_init(void)
|
wifi_station_wps_init(void)
|
||||||
{
|
{
|
||||||
struct wps_funcs *wps_cb;
|
struct wps_funcs *wps_cb;
|
||||||
struct wps_sm *sm = NULL;
|
struct wps_sm *sm = NULL;
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
|
struct wps_config cfg = {0};
|
||||||
|
|
||||||
if (gWpsSm) {
|
if (gWpsSm) {
|
||||||
goto _out;
|
goto _out;
|
||||||
@@ -1613,30 +1396,20 @@ wifi_station_wps_init(void)
|
|||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "wifi sta wps init");
|
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) {
|
if (!gWpsSm) {
|
||||||
goto _out;
|
goto _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sm = gWpsSm;
|
sm = gWpsSm;
|
||||||
os_memset(sm, 0x00, sizeof(struct wps_sm));
|
|
||||||
|
|
||||||
esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac);
|
esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac);
|
||||||
os_memcpy(sm->ownaddr, mac, ETH_ALEN);
|
os_memcpy(sm->ownaddr, mac, ETH_ALEN);
|
||||||
|
|
||||||
sm->discover_ssid_cnt = 0;
|
sm->identity_len = WSC_ID_ENROLLEE_LEN;
|
||||||
sm->ignore_sel_reg = false;
|
os_memcpy(sm->identity, WSC_ID_ENROLLEE, sm->identity_len);
|
||||||
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->is_wps_scan = false;
|
sm->wps_ctx = os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
|
||||||
|
|
||||||
sm->wps_ctx = (struct wps_context *)os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
|
|
||||||
if (!sm->wps_ctx) {
|
if (!sm->wps_ctx) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
@@ -1645,10 +1418,42 @@ wifi_station_wps_init(void)
|
|||||||
goto _err;
|
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;
|
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***************/
|
/**************80211 reference***************/
|
||||||
|
|
||||||
if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_PR) == NULL) { /* alloc probe req wps ie */
|
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_disarm(&sm->wps_eapol_start_timer);
|
||||||
ets_timer_setfn(&sm->wps_eapol_start_timer, (ETSTimerFunc *)wifi_station_wps_eapol_start_handle, NULL);
|
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));
|
wps_cb = os_malloc(sizeof(struct wps_funcs));
|
||||||
if (wps_cb == NULL) {
|
if (wps_cb == NULL) {
|
||||||
goto _err;
|
goto _err;
|
||||||
@@ -1698,7 +1501,7 @@ _err:
|
|||||||
sm->wps_ctx = NULL;
|
sm->wps_ctx = NULL;
|
||||||
}
|
}
|
||||||
if (sm->wps) {
|
if (sm->wps) {
|
||||||
wps_deinit();
|
wps_deinit(sm->wps);
|
||||||
sm->wps = NULL;
|
sm->wps = NULL;
|
||||||
}
|
}
|
||||||
os_free(gWpsSm);
|
os_free(gWpsSm);
|
||||||
@@ -1752,7 +1555,7 @@ wifi_station_wps_deinit(void)
|
|||||||
sm->wps_ctx = NULL;
|
sm->wps_ctx = NULL;
|
||||||
}
|
}
|
||||||
if (sm->wps) {
|
if (sm->wps) {
|
||||||
wps_deinit();
|
wps_deinit(sm->wps);
|
||||||
sm->wps = NULL;
|
sm->wps = NULL;
|
||||||
}
|
}
|
||||||
os_free(gWpsSm);
|
os_free(gWpsSm);
|
||||||
@@ -1761,73 +1564,17 @@ wifi_station_wps_deinit(void)
|
|||||||
return ESP_OK;
|
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 *
|
struct wps_sm *
|
||||||
wps_sm_get(void)
|
wps_sm_get(void)
|
||||||
{
|
{
|
||||||
return gWpsSm;
|
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
|
void
|
||||||
wifi_wps_scan_done(void *arg, STATUS status)
|
wifi_wps_scan_done(void *arg, STATUS status)
|
||||||
{
|
{
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
wifi_config_t wifi_config;
|
wifi_config_t wifi_config = {0};
|
||||||
|
|
||||||
wpa_printf(MSG_INFO, "WPS: scan done");
|
wpa_printf(MSG_INFO, "WPS: scan done");
|
||||||
if (wps_get_type() == WPS_TYPE_DISABLE) {
|
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) {
|
if (wps_get_status() == WPS_STATUS_PENDING) {
|
||||||
esp_wifi_disconnect();
|
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);
|
esp_wifi_set_config(0, &wifi_config);
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: neg start");
|
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);
|
ets_timer_arm(&sm->wps_msg_timeout_timer, 2000, 0);
|
||||||
} else if (wps_get_status() == WPS_STATUS_SCANNING) {
|
} else if (wps_get_status() == WPS_STATUS_SCANNING) {
|
||||||
if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) {
|
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->ignore_sel_reg = true;
|
||||||
sm->wps_pin_war = false;
|
|
||||||
}
|
}
|
||||||
ets_timer_arm(&sm->wps_scan_timer, 100, 0);
|
ets_timer_arm(&sm->wps_scan_timer, 100, 0);
|
||||||
} else {
|
} else {
|
||||||
@@ -1911,11 +1662,14 @@ int wifi_station_wps_start(void)
|
|||||||
case WPS_STATUS_DISABLE: {
|
case WPS_STATUS_DISABLE: {
|
||||||
sm->is_wps_scan = true;
|
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();
|
wifi_wps_scan();
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WPS_STATUS_SCANNING:
|
case WPS_STATUS_SCANNING:
|
||||||
@@ -2230,24 +1984,3 @@ int esp_wifi_wps_start(int timeout_ms)
|
|||||||
API_MUTEX_GIVE();
|
API_MUTEX_GIVE();
|
||||||
return ESP_OK;
|
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;
|
|
||||||
}
|
|
||||||
|
80
components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h
Normal file
80
components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h
Normal 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);
|
@@ -515,6 +515,12 @@ struct ieee80211_ht_operation {
|
|||||||
#define HT_OPER_PARAM_PCO_PHASE ((u16) BIT(11))
|
#define HT_OPER_PARAM_PCO_PHASE ((u16) BIT(11))
|
||||||
/* B36..B39 - Reserved */
|
/* 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_TYPE 2
|
||||||
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
|
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
|
||||||
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
|
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
|
||||||
|
@@ -354,7 +354,7 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
|
|||||||
struct os_reltime now;
|
struct os_reltime now;
|
||||||
|
|
||||||
if (os_get_reltime(&now) == 0 &&
|
if (os_get_reltime(&now) == 0 &&
|
||||||
os_time_expired(&now, &target->last_update,
|
os_reltime_expired(&now, &target->last_update,
|
||||||
age_secs)) {
|
age_secs)) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"Candidate BSS is more than %jd seconds old",
|
"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.
|
* list.
|
||||||
*/
|
*/
|
||||||
os_get_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))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG,
|
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;
|
struct os_reltime now;
|
||||||
|
|
||||||
os_get_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,
|
wpa_printf(MSG_DEBUG,
|
||||||
"WNM: Try to use recent scan results");
|
"WNM: Try to use recent scan results");
|
||||||
if (wnm_scan_process(wpa_s, 0) > 0)
|
if (wnm_scan_process(wpa_s, 0) > 0)
|
||||||
|
33
components/wpa_supplicant/src/eap_common/eap_wsc_common.c
Normal file
33
components/wpa_supplicant/src/eap_common/eap_wsc_common.c
Normal 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;
|
||||||
|
}
|
27
components/wpa_supplicant/src/eap_common/eap_wsc_common.h
Normal file
27
components/wpa_supplicant/src/eap_common/eap_wsc_common.h
Normal 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 */
|
@@ -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)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
* @dest: Destination MAC address
|
* @dest: Destination MAC address
|
||||||
* @proto: Ethertype in host byte order
|
* @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
|
* @len: Frame payload length
|
||||||
* Returns: >=0 on success, <0 on failure
|
* 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)
|
const u8 *data, size_t data_len)
|
||||||
{
|
{
|
||||||
void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
|
return wpa_ether_send(sm, dest, proto, data, data_len);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2176,7 +2168,7 @@ bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func,
|
|||||||
struct wpa_sm *sm = &gWpaSm;
|
struct wpa_sm *sm = &gWpaSm;
|
||||||
u16 spp_attrubute = 0;
|
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->sendto = snd_func;
|
||||||
sm->config_assoc_ie = set_assoc_ie_func;
|
sm->config_assoc_ie = set_assoc_ie_func;
|
||||||
sm->install_ppkey = ppinstallkey;
|
sm->install_ppkey = ppinstallkey;
|
||||||
|
@@ -19,10 +19,10 @@
|
|||||||
#include "wpa_i.h"
|
#include "wpa_i.h"
|
||||||
|
|
||||||
struct wpa_sm;
|
struct wpa_sm;
|
||||||
|
extern struct wpa_sm gWpaSm;
|
||||||
|
|
||||||
#define WPA_SM_STATE(_sm) ((_sm)->wpa_state)
|
#define WPA_SM_STATE(_sm) ((_sm)->wpa_state)
|
||||||
|
|
||||||
|
|
||||||
bool wpa_sta_is_cur_pmksa_set(void);
|
bool wpa_sta_is_cur_pmksa_set(void);
|
||||||
bool wpa_sta_in_4way_handshake(void);
|
bool wpa_sta_in_4way_handshake(void);
|
||||||
bool wpa_sta_cur_pmksa_matches_akm(void);
|
bool wpa_sta_cur_pmksa_matches_akm(void);
|
||||||
|
@@ -10,6 +10,8 @@
|
|||||||
#define WPA_I_H
|
#define WPA_I_H
|
||||||
|
|
||||||
extern struct wpa_sm gWpaSm;
|
extern struct wpa_sm gWpaSm;
|
||||||
|
#define DEFAULT_EAPOL_VERSION 1
|
||||||
|
|
||||||
struct install_key {
|
struct install_key {
|
||||||
int keys_cleared;
|
int keys_cleared;
|
||||||
enum wpa_alg alg;
|
enum wpa_alg alg;
|
||||||
|
@@ -1,35 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* wpa_supplicant/hostapd / common helper functions, etc.
|
* 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.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "includes.h"
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "utils/common.h"
|
|
||||||
#include <time.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)
|
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
|
* hexstr2bin - Convert ASCII hex string into binary data
|
||||||
* @hex: ASCII hex string (e.g., "01ab")
|
* @hex: ASCII hex string (e.g., "01ab")
|
||||||
@@ -81,6 +94,28 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len)
|
|||||||
return 0;
|
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)
|
void wpa_get_ntp_timestamp(u8 *buf)
|
||||||
{
|
{
|
||||||
struct os_time now;
|
struct os_time now;
|
||||||
@@ -133,7 +168,7 @@ void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
|
|||||||
*txt++ = 't';
|
*txt++ = 't';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (data[i] >= 32 && data[i] <= 127) {
|
if (data[i] >= 32 && data[i] <= 126) {
|
||||||
*txt++ = data[i];
|
*txt++ = data[i];
|
||||||
} else {
|
} else {
|
||||||
txt += os_snprintf(txt, end - txt, "\\x%02x",
|
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)
|
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,
|
size_t wpa_merge_byte_arrays(u8 *res, size_t res_len,
|
||||||
const u8 *src1, size_t src1_len,
|
const u8 *src1, size_t src1_len,
|
||||||
const u8 *src2, size_t src2_len)
|
const u8 *src2, size_t src2_len)
|
||||||
@@ -358,39 +439,36 @@ char * dup_binstr(const void *src, size_t len)
|
|||||||
|
|
||||||
return res;
|
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++)
|
for (i = 0; a && a[i]; i++)
|
||||||
;
|
;
|
||||||
return 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)
|
void str_clear_free(char *str)
|
||||||
{
|
{
|
||||||
if (str) {
|
if (str) {
|
||||||
size_t len = os_strlen(str);
|
size_t len = os_strlen(str);
|
||||||
os_memset(str, 0, len);
|
forced_memzero(str, len);
|
||||||
os_free(str);
|
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)
|
int os_gmtime(os_time_t t, struct os_tm *tm)
|
||||||
{
|
{
|
||||||
struct tm *tm2;
|
struct tm *tm2;
|
||||||
@@ -430,6 +508,39 @@ int os_mktime(int year, int month, int day, int hour, int min, int sec,
|
|||||||
return 0;
|
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)
|
char * get_param(const char *cmd, const char *param)
|
||||||
{
|
{
|
||||||
const char *pos, *end;
|
const char *pos, *end;
|
||||||
@@ -453,102 +564,3 @@ char * get_param(const char *cmd, const char *param)
|
|||||||
val[len] = '\0';
|
val[len] = '\0';
|
||||||
return val;
|
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;
|
|
||||||
}
|
|
||||||
|
@@ -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);
|
int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask);
|
||||||
u8 rssi_to_rcpi(int rssi);
|
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,
|
struct os_time *ts,
|
||||||
os_time_t timeout_secs);
|
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);
|
char * wpa_config_parse_string(const char *value, size_t *len);
|
||||||
int wpa_is_hex(const u8 *data, 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,
|
size_t wpa_merge_byte_arrays(u8 *res, size_t res_len,
|
||||||
const u8 *src1, size_t src1_len,
|
const u8 *src1, size_t src1_len,
|
||||||
const u8 *src2, size_t src2_len);
|
const u8 *src2, size_t src2_len);
|
||||||
@@ -447,8 +448,7 @@ struct wpa_freq_range_list {
|
|||||||
#define TEST_FAIL() 0
|
#define TEST_FAIL() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void wpa_bin_clear_free(void *bin, size_t len);
|
size_t int_array_len(const int *a);
|
||||||
int int_array_len(const int *a);
|
|
||||||
void bin_clear_free(void *bin, size_t len);
|
void bin_clear_free(void *bin, size_t len);
|
||||||
void str_clear_free(char *str);
|
void str_clear_free(char *str);
|
||||||
char * get_param(const char *cmd, const char *param);
|
char * get_param(const char *cmd, const char *param);
|
||||||
|
@@ -1,15 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* wpa_supplicant/hostapd / Debug prints
|
* 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
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* See README for more details.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
#ifdef ESP_SUPPLICANT
|
#ifdef ESP_SUPPLICANT
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
@@ -5,20 +5,191 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "includes.h"
|
||||||
#include "rsn_supp/wpa.h"
|
|
||||||
#include "utils/common.h"
|
#include "common.h"
|
||||||
#include "common/eapol_common.h"
|
#include "crypto/dh_group5.h"
|
||||||
#include "utils/wpa_debug.h"
|
|
||||||
#include "common/ieee802_11_defs.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"
|
#ifdef CONFIG_WPS_TESTING
|
||||||
#include "eap_peer/eap_common.h"
|
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)
|
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)
|
if (!attr)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -103,7 +274,6 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_PIN
|
|
||||||
|
|
||||||
static int is_selected_pin_registrar(struct wps_parse_attr *attr)
|
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;
|
struct wps_parse_attr *attr;
|
||||||
int ret;
|
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)
|
if (attr == NULL)
|
||||||
return -99;
|
return -99;
|
||||||
|
|
||||||
@@ -157,7 +327,6 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wps_is_addr_authorized - Check whether WPS IE authorizes MAC address
|
* 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 *pos;
|
||||||
const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
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) {
|
if (attr == NULL) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto _out;
|
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
|
* Version 1.0 AP - AuthorizedMACs not used, so revert back to
|
||||||
* old mechanism of using SelectedRegistrar.
|
* old mechanism of using SelectedRegistrar.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_WPS_PIN
|
|
||||||
|
|
||||||
ret = is_selected_pin_registrar(attr);
|
ret = is_selected_pin_registrar(attr);
|
||||||
goto _out;
|
goto _out;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attr->authorized_macs) {
|
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) ||
|
if (wps_build_version(ie) ||
|
||||||
wps_build_req_type(ie, req_type) ||
|
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);
|
wpabuf_free(ie);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -377,7 +544,7 @@ struct wpabuf * wps_build_assoc_resp_ie(void)
|
|||||||
|
|
||||||
if (wps_build_version(ie) ||
|
if (wps_build_version(ie) ||
|
||||||
wps_build_resp_type(ie, WPS_RESP_AP) ||
|
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);
|
wpabuf_free(ie);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -410,30 +577,26 @@ struct wpabuf * wps_build_probe_req_ie(u16 pw_id, struct wps_device_data *dev,
|
|||||||
{
|
{
|
||||||
struct wpabuf *ie;
|
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);
|
ie = wpabuf_alloc(500);
|
||||||
if (ie == NULL) {
|
if (ie == NULL)
|
||||||
wpa_printf(MSG_ERROR, "WPS: ie alloc failed.");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (wps_build_version(ie) ||
|
if (wps_build_version(ie) ||
|
||||||
wps_build_req_type(ie, req_type) ||
|
wps_build_req_type(ie, req_type) ||
|
||||||
wps_build_config_methods(ie, dev->config_methods) ||
|
wps_build_config_methods(ie, dev->config_methods) ||
|
||||||
wps_build_uuid_e(ie, uuid) ||
|
wps_build_uuid_e(ie, uuid) ||
|
||||||
wps_build_primary_dev_type(dev, ie) ||
|
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_assoc_state(NULL, ie) ||
|
||||||
wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
|
wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
|
||||||
wps_build_dev_password_id(ie, pw_id) ||
|
wps_build_dev_password_id(ie, pw_id) ||
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
wps_build_manufacturer(dev, ie) ||
|
wps_build_manufacturer(dev, ie) ||
|
||||||
wps_build_model_name(dev, ie) ||
|
wps_build_model_name(dev, ie) ||
|
||||||
wps_build_model_number(dev, ie) ||
|
wps_build_model_number(dev, ie) ||
|
||||||
wps_build_dev_name(dev, ie) ||
|
wps_build_dev_name(dev, ie) ||
|
||||||
wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
|
wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
|
wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
|
||||||
||
|
||
|
||||||
wps_build_secondary_dev_type(dev, ie)
|
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;
|
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);
|
return wps_ie_encapsulate(ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Wi-Fi Protected Setup
|
* 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.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
@@ -9,13 +9,8 @@
|
|||||||
#ifndef WPS_H
|
#ifndef WPS_H
|
||||||
#define WPS_H
|
#define WPS_H
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#include "common/ieee802_11_defs.h"
|
||||||
#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 "wps_defs.h"
|
#include "wps_defs.h"
|
||||||
#include "esp_wifi_types.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum wsc_op_code - EAP-WSC OP-Code values
|
* enum wsc_op_code - EAP-WSC OP-Code values
|
||||||
@@ -31,6 +26,7 @@ enum wsc_op_code {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct wps_registrar;
|
struct wps_registrar;
|
||||||
|
struct upnp_wps_device_sm;
|
||||||
struct wps_er;
|
struct wps_er;
|
||||||
struct wps_parse_attr;
|
struct wps_parse_attr;
|
||||||
|
|
||||||
@@ -38,7 +34,7 @@ struct wps_parse_attr;
|
|||||||
* struct wps_credential - WPS Credential
|
* struct wps_credential - WPS Credential
|
||||||
* @ssid: SSID
|
* @ssid: SSID
|
||||||
* @ssid_len: Length of 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)
|
* @encr_type: Encryption Type (WPS_ENCR_NONE, .. flags)
|
||||||
* @key_idx: Key index
|
* @key_idx: Key index
|
||||||
* @key: Key
|
* @key: Key
|
||||||
@@ -47,10 +43,9 @@ struct wps_parse_attr;
|
|||||||
* @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
|
* @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
|
||||||
* this may be %NULL, if not used
|
* this may be %NULL, if not used
|
||||||
* @cred_attr_len: Length of cred_attr in octets
|
* @cred_attr_len: Length of cred_attr in octets
|
||||||
* @ap_channel: AP channel
|
|
||||||
*/
|
*/
|
||||||
struct wps_credential {
|
struct wps_credential {
|
||||||
u8 ssid[32];
|
u8 ssid[SSID_MAX_LEN];
|
||||||
size_t ssid_len;
|
size_t ssid_len;
|
||||||
u16 auth_type;
|
u16 auth_type;
|
||||||
u16 encr_type;
|
u16 encr_type;
|
||||||
@@ -60,7 +55,6 @@ struct wps_credential {
|
|||||||
u8 mac_addr[ETH_ALEN];
|
u8 mac_addr[ETH_ALEN];
|
||||||
const u8 *cred_attr;
|
const u8 *cred_attr;
|
||||||
size_t cred_attr_len;
|
size_t cred_attr_len;
|
||||||
u16 ap_channel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WPS_DEV_TYPE_LEN 8
|
#define WPS_DEV_TYPE_LEN 8
|
||||||
@@ -85,7 +79,7 @@ struct wps_credential {
|
|||||||
* @sec_dev_type: Array of secondary device types
|
* @sec_dev_type: Array of secondary device types
|
||||||
* @num_sec_dev_type: Number of secondary device types
|
* @num_sec_dev_type: Number of secondary device types
|
||||||
* @os_version: OS Version
|
* @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
|
* @p2p: Whether the device is a P2P device
|
||||||
*/
|
*/
|
||||||
struct wps_device_data {
|
struct wps_device_data {
|
||||||
@@ -104,8 +98,10 @@ struct wps_device_data {
|
|||||||
u16 config_methods;
|
u16 config_methods;
|
||||||
struct wpabuf *vendor_ext_m1;
|
struct wpabuf *vendor_ext_m1;
|
||||||
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||||
|
struct wpabuf *application_ext;
|
||||||
|
|
||||||
int p2p;
|
int p2p;
|
||||||
|
u8 multi_ap_ext;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +132,7 @@ struct wps_config {
|
|||||||
* pbc - Whether this is protocol run uses PBC
|
* pbc - Whether this is protocol run uses PBC
|
||||||
*/
|
*/
|
||||||
int pbc;
|
int pbc;
|
||||||
|
#ifndef ESP_SUPPLICANT
|
||||||
/**
|
/**
|
||||||
* assoc_wps_ie: (Re)AssocReq WPS IE (in AP; %NULL if not AP)
|
* assoc_wps_ie: (Re)AssocReq WPS IE (in AP; %NULL if not AP)
|
||||||
*/
|
*/
|
||||||
@@ -166,11 +162,13 @@ struct wps_config {
|
|||||||
*/
|
*/
|
||||||
int use_psk_key;
|
int use_psk_key;
|
||||||
|
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* dev_pw_id - Device Password ID for Enrollee when PIN is used
|
* dev_pw_id - Device Password ID for Enrollee when PIN is used
|
||||||
*/
|
*/
|
||||||
u16 dev_pw_id;
|
u16 dev_pw_id;
|
||||||
|
|
||||||
|
#ifndef ESP_SUPPLICANT
|
||||||
/**
|
/**
|
||||||
* p2p_dev_addr - P2P Device Address from (Re)Association Request
|
* p2p_dev_addr - P2P Device Address from (Re)Association Request
|
||||||
*
|
*
|
||||||
@@ -188,16 +186,23 @@ struct wps_config {
|
|||||||
* PBC with the AP.
|
* PBC with the AP.
|
||||||
*/
|
*/
|
||||||
int pbc_in_m1;
|
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 wps_data * wps_init(const struct wps_config *cfg);
|
||||||
struct discard_ap_list_t{
|
|
||||||
u8 bssid[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wps_data * wps_init(void);
|
void wps_deinit(struct wps_data *data);
|
||||||
|
|
||||||
void wps_deinit(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum wps_process_res - WPS message processing result
|
* enum wps_process_res - WPS message processing result
|
||||||
@@ -259,14 +264,15 @@ struct wps_registrar_config {
|
|||||||
* new_psk_cb - Callback for new PSK
|
* new_psk_cb - Callback for new PSK
|
||||||
* @ctx: Higher layer context data (cb_ctx)
|
* @ctx: Higher layer context data (cb_ctx)
|
||||||
* @mac_addr: MAC address of the Enrollee
|
* @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: The new PSK
|
||||||
* @psk_len: The length of psk in octets
|
* @psk_len: The length of psk in octets
|
||||||
* Returns: 0 on success, -1 on failure
|
* Returns: 0 on success, -1 on failure
|
||||||
*
|
*
|
||||||
* This callback is called when a new per-device PSK is provisioned.
|
* 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,
|
int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
|
||||||
size_t psk_len);
|
const u8 *psk, size_t psk_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_ie_cb - Callback for WPS IE changes
|
* set_ie_cb - Callback for WPS IE changes
|
||||||
@@ -344,6 +350,14 @@ struct wps_registrar_config {
|
|||||||
u16 dev_password_id, u8 request_type,
|
u16 dev_password_id, u8 request_type,
|
||||||
const char *dev_name);
|
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
|
* cb_ctx: Higher layer context data for Registrar callbacks
|
||||||
*/
|
*/
|
||||||
@@ -386,15 +400,49 @@ struct wps_registrar_config {
|
|||||||
*/
|
*/
|
||||||
int disable_auto_conf;
|
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
|
* dualband - Whether this is a concurrent dualband AP
|
||||||
*/
|
*/
|
||||||
int dualband;
|
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_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
|
* WPS_EV_ER_AP_ADD - ER: AP added
|
||||||
*/
|
*/
|
||||||
@@ -500,11 +558,17 @@ union wps_event_data {
|
|||||||
int msg;
|
int msg;
|
||||||
u16 config_error;
|
u16 config_error;
|
||||||
u16 error_indication;
|
u16 error_indication;
|
||||||
|
u8 peer_macaddr[ETH_ALEN];
|
||||||
} fail;
|
} fail;
|
||||||
|
|
||||||
|
struct wps_event_success {
|
||||||
|
u8 peer_macaddr[ETH_ALEN];
|
||||||
|
} success;
|
||||||
|
|
||||||
struct wps_event_pwd_auth_fail {
|
struct wps_event_pwd_auth_fail {
|
||||||
int enrollee;
|
int enrollee;
|
||||||
int part;
|
int part;
|
||||||
|
u8 peer_macaddr[ETH_ALEN];
|
||||||
} pwd_auth_fail;
|
} pwd_auth_fail;
|
||||||
|
|
||||||
struct wps_event_er_ap {
|
struct wps_event_er_ap {
|
||||||
@@ -568,7 +632,6 @@ struct upnp_pending_message {
|
|||||||
struct wpabuf *msg;
|
struct wpabuf *msg;
|
||||||
enum wps_msg_type type;
|
enum wps_msg_type type;
|
||||||
};
|
};
|
||||||
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
|
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* struct wps_context - Long term WPS context data
|
* 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
|
* Credentials. In addition, AP uses it when acting as an Enrollee to
|
||||||
* notify Registrar of the current configuration.
|
* notify Registrar of the current configuration.
|
||||||
*/
|
*/
|
||||||
u8 ssid[32];
|
u8 ssid[SSID_MAX_LEN];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ssid_len - Length of ssid in octets
|
* ssid_len - Length of ssid in octets
|
||||||
@@ -648,11 +711,31 @@ struct wps_context {
|
|||||||
*/
|
*/
|
||||||
u16 encr_types;
|
u16 encr_types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encr_types_rsn - Enabled encryption types for RSN (WPS_ENCR_*)
|
||||||
|
*/
|
||||||
|
u16 encr_types_rsn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encr_types_wpa - Enabled encryption types for WPA (WPS_ENCR_*)
|
||||||
|
*/
|
||||||
|
u16 encr_types_wpa;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* auth_types - Authentication types (bit field of WPS_AUTH_*)
|
* auth_types - Authentication types (bit field of WPS_AUTH_*)
|
||||||
*/
|
*/
|
||||||
u16 auth_types;
|
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
|
* 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
|
* uses this when acting as an Enrollee to notify Registrar of the
|
||||||
* current configuration.
|
* current configuration.
|
||||||
*
|
*
|
||||||
* When using WPA/WPA2-Person, this key can be either the ASCII
|
* When using WPA/WPA2-Personal, this key can be either the ASCII
|
||||||
* passphrase (8..63 characters) or the 32-octet PSK (64 hex
|
* passphrase (8..63 characters) or the 32-octet PSK (64 hex
|
||||||
* characters). When this is set to the ASCII passphrase, the PSK can
|
* 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
|
* 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,
|
void (*event_cb)(void *ctx, enum wps_event event,
|
||||||
union wps_event_data *data);
|
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
|
* cb_ctx: Higher layer context data for callbacks
|
||||||
*/
|
*/
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
|
|
||||||
|
struct upnp_wps_device_sm *wps_upnp;
|
||||||
|
|
||||||
/* Pending messages from UPnP PutWLANResponse */
|
/* Pending messages from UPnP PutWLANResponse */
|
||||||
#ifdef CONFIG_WPS_NFC
|
struct upnp_pending_message *upnp_msgs;
|
||||||
|
|
||||||
u16 ap_nfc_dev_pw_id;
|
u16 ap_nfc_dev_pw_id;
|
||||||
struct wpabuf *ap_nfc_dh_pubkey;
|
struct wpabuf *ap_nfc_dh_pubkey;
|
||||||
struct wpabuf *ap_nfc_dh_privkey;
|
struct wpabuf *ap_nfc_dh_privkey;
|
||||||
struct wpabuf *ap_nfc_dev_pw;
|
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 *
|
struct wps_registrar *
|
||||||
wps_registrar_init(struct wps_context *wps,
|
wps_registrar_init(struct wps_context *wps,
|
||||||
const struct wps_registrar_config *cfg);
|
const struct wps_registrar_config *cfg);
|
||||||
void wps_registrar_deinit(struct wps_registrar *reg);
|
void wps_registrar_deinit(struct wps_registrar *reg);
|
||||||
#ifdef CONFIG_WPS_PIN
|
|
||||||
|
|
||||||
int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
|
int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
|
||||||
const u8 *uuid, const u8 *pin, size_t pin_len,
|
const u8 *uuid, const u8 *pin, size_t pin_len,
|
||||||
int timeout);
|
int timeout);
|
||||||
int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid);
|
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_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,
|
int wps_registrar_button_pushed(struct wps_registrar *reg,
|
||||||
const u8 *p2p_dev_addr);
|
const u8 *p2p_dev_addr);
|
||||||
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
|
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,
|
int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
|
||||||
const u8 *pubkey_hash, u16 pw_id,
|
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,
|
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
||||||
const u8 *oob_dev_pw,
|
const u8 *oob_dev_pw,
|
||||||
size_t oob_dev_pw_len);
|
size_t oob_dev_pw_len);
|
||||||
#endif
|
#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,
|
int wps_build_credential_wrap(struct wpabuf *msg,
|
||||||
const struct wps_credential *cred);
|
const struct wps_credential *cred);
|
||||||
#ifdef CONFIG_WPS_PIN
|
|
||||||
unsigned int wps_pin_checksum(unsigned int pin);
|
unsigned int wps_pin_checksum(unsigned int pin);
|
||||||
unsigned int wps_pin_valid(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);
|
int wps_pin_str_valid(const char *pin);
|
||||||
#endif
|
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
|
||||||
|
|
||||||
unsigned int wps_generate_pin(void);
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
struct wpabuf * wps_get_oob_cred(struct wps_context *wps, int rf_band,
|
||||||
struct wpabuf * wps_get_oob_cred(struct wps_context *wps);
|
int channel);
|
||||||
int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr);
|
int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr);
|
||||||
#endif
|
#endif
|
||||||
int wps_attr_text(struct wpabuf *data, char *buf, char *end);
|
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,
|
struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname,
|
||||||
const char *filter);
|
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_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,
|
void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
|
||||||
u16 sel_reg_config_methods);
|
u16 sel_reg_config_methods);
|
||||||
int wps_er_pbc(struct wps_er *er, const u8 *uuid);
|
int wps_er_pbc(struct wps_er *er, const u8 *uuid, const u8 *addr);
|
||||||
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
const u8 * wps_er_get_sta_uuid(struct wps_er *er, const u8 *addr);
|
||||||
size_t pin_len);
|
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
int wps_er_set_config(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, const u8 *addr,
|
||||||
const struct wps_credential *cred);
|
const struct wps_credential *cred);
|
||||||
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
size_t pin_len, const struct wps_credential *cred);
|
const u8 *pin, size_t pin_len,
|
||||||
#ifdef CONFIG_WPS_NFC
|
const struct wps_credential *cred);
|
||||||
|
struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
|
||||||
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid);
|
struct wps_credential *cred);
|
||||||
|
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
|
||||||
#endif
|
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]);
|
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,
|
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,
|
struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id,
|
||||||
const struct wpabuf *pubkey,
|
const struct wpabuf *pubkey,
|
||||||
const struct wpabuf *dev_pw);
|
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 * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
|
||||||
struct wpabuf **privkey,
|
struct wpabuf **privkey,
|
||||||
struct wpabuf **dev_pw);
|
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
|
#endif
|
||||||
|
|
||||||
/* ndef.c */
|
/* ndef.c */
|
||||||
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
|
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
|
||||||
struct wpabuf * ndef_build_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
|
#ifdef CONFIG_WPS_STRICT
|
||||||
int wps_validate_beacon(const struct wpabuf *wps_ie);
|
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 */
|
#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 */
|
#endif /* WPS_H */
|
||||||
|
@@ -1,86 +1,99 @@
|
|||||||
/*
|
/*
|
||||||
* Wi-Fi Protected Setup - attribute building
|
* 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.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* 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/aes_wrap.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
|
#include "crypto/dh_group5.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
#include "crypto/random.h"
|
#include "crypto/random.h"
|
||||||
#include "crypto/dh_group5.h"
|
|
||||||
|
|
||||||
#include "common/ieee802_11_defs.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;
|
struct wpabuf *pubkey = NULL;
|
||||||
|
|
||||||
if (mode != WPS_CALC_KEY_NO_CALC) {
|
wpa_printf(MSG_DEBUG, "WPS: * Public Key");
|
||||||
|
wpabuf_clear_free(wps->dh_privkey);
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Public Key");
|
wps->dh_privkey = NULL;
|
||||||
wpabuf_free(wps->dh_privkey);
|
if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey &&
|
||||||
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");
|
wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
|
||||||
wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
|
if (wps->wps->dh_pubkey == NULL) {
|
||||||
wps->dh_ctx = wps->wps->dh_ctx;
|
wpa_printf(MSG_DEBUG,
|
||||||
wps->wps->dh_ctx = NULL;
|
"WPS: wps->wps->dh_pubkey == 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) {
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys");
|
|
||||||
wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey);
|
|
||||||
pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_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) {
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
|
|
||||||
"Diffie-Hellman handshake");
|
|
||||||
wpabuf_free(pubkey);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
|
wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
|
||||||
wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey);
|
wps->dh_ctx = wps->wps->dh_ctx;
|
||||||
|
wps->wps->dh_ctx = NULL;
|
||||||
if (wps->registrar) {
|
pubkey = wpabuf_dup(wps->wps->dh_pubkey);
|
||||||
wpabuf_free(wps->dh_pubkey_r);
|
#ifdef CONFIG_WPS_NFC
|
||||||
wps->dh_pubkey_r = pubkey;
|
} else if ((wps->dev_pw_id >= 0x10 ||
|
||||||
} else {
|
wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) &&
|
||||||
wpabuf_free(wps->dh_pubkey_e);
|
(wps->wps->ap ||
|
||||||
wps->dh_pubkey_e = pubkey;
|
(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");
|
||||||
|
dh5_free(wps->dh_ctx);
|
||||||
|
wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
|
||||||
|
pubkey = wpabuf_zeropad(pubkey, 192);
|
||||||
}
|
}
|
||||||
|
if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
|
||||||
|
"Diffie-Hellman handshake");
|
||||||
|
wpabuf_free(pubkey);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey);
|
||||||
|
|
||||||
if (mode != WPS_CALC_KEY_PRE_CALC) {
|
#ifdef ESP_SUPPLICANT
|
||||||
if (wps->registrar)
|
if (msg) {
|
||||||
pubkey = wps->dh_pubkey_r;
|
#endif
|
||||||
else
|
wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
|
||||||
pubkey = wps->dh_pubkey_e;
|
wpabuf_put_be16(msg, wpabuf_len(pubkey));
|
||||||
|
wpabuf_put_buf(msg, pubkey);
|
||||||
|
#ifdef ESP_SUPPLICANT
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
|
if (wps->registrar) {
|
||||||
wpabuf_put_be16(msg, wpabuf_len(pubkey));
|
wpabuf_free(wps->dh_pubkey_r);
|
||||||
wpabuf_put_buf(msg, pubkey);
|
wps->dh_pubkey_r = pubkey;
|
||||||
|
} else {
|
||||||
|
wpabuf_free(wps->dh_pubkey_e);
|
||||||
|
wps->dh_pubkey_e = pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -89,7 +102,7 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg, wps_key_mode_
|
|||||||
|
|
||||||
int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
|
int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Request Type");
|
wpa_printf(MSG_DEBUG, "WPS: * Request Type");
|
||||||
wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
|
wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
wpabuf_put_u8(msg, type);
|
wpabuf_put_u8(msg, type);
|
||||||
@@ -99,7 +112,7 @@ 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_resp_type(struct wpabuf *msg, enum wps_response_type type)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", type);
|
wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", type);
|
||||||
wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
|
wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
wpabuf_put_u8(msg, type);
|
wpabuf_put_u8(msg, type);
|
||||||
@@ -109,7 +122,7 @@ int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type)
|
|||||||
|
|
||||||
int wps_build_config_methods(struct wpabuf *msg, u16 methods)
|
int wps_build_config_methods(struct wpabuf *msg, u16 methods)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
|
wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
|
||||||
wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
|
wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, methods);
|
wpabuf_put_be16(msg, methods);
|
||||||
@@ -119,7 +132,9 @@ int wps_build_config_methods(struct wpabuf *msg, u16 methods)
|
|||||||
|
|
||||||
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
|
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
|
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, ATTR_UUID_E);
|
||||||
wpabuf_put_be16(msg, WPS_UUID_LEN);
|
wpabuf_put_be16(msg, WPS_UUID_LEN);
|
||||||
wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
|
wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
|
||||||
@@ -129,7 +144,7 @@ int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
|
|||||||
|
|
||||||
int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
|
int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
|
wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
|
||||||
wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
|
wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, id);
|
wpabuf_put_be16(msg, id);
|
||||||
@@ -139,7 +154,7 @@ int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
|
|||||||
|
|
||||||
int wps_build_config_error(struct wpabuf *msg, u16 err)
|
int wps_build_config_error(struct wpabuf *msg, u16 err)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err);
|
wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err);
|
||||||
wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
|
wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, err);
|
wpabuf_put_be16(msg, err);
|
||||||
@@ -154,7 +169,7 @@ int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
size_t len[2];
|
size_t len[2];
|
||||||
|
|
||||||
if (wps->last_msg == NULL) {
|
if (wps->last_msg == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
|
wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
|
||||||
"building authenticator");
|
"building authenticator");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -166,8 +181,11 @@ int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
len[0] = wpabuf_len(wps->last_msg);
|
len[0] = wpabuf_len(wps->last_msg);
|
||||||
addr[1] = wpabuf_head(msg);
|
addr[1] = wpabuf_head(msg);
|
||||||
len[1] = wpabuf_len(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,
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Authenticator");
|
hash) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: * Authenticator");
|
||||||
wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
|
wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
|
||||||
wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
|
wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
|
||||||
wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
|
wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
|
||||||
@@ -183,7 +201,9 @@ int wps_build_version(struct wpabuf *msg)
|
|||||||
* backwards compatibility reasons. The real version negotiation is
|
* backwards compatibility reasons. The real version negotiation is
|
||||||
* done with Version2.
|
* done with Version2.
|
||||||
*/
|
*/
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Version (hardcoded 0x10)");
|
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, ATTR_VERSION);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
wpabuf_put_u8(msg, 0x10);
|
wpabuf_put_u8(msg, 0x10);
|
||||||
@@ -192,22 +212,31 @@ int wps_build_version(struct wpabuf *msg)
|
|||||||
|
|
||||||
|
|
||||||
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
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;
|
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);
|
wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
|
||||||
len = wpabuf_put(msg, 2); /* to be filled */
|
len = wpabuf_put(msg, 2); /* to be filled */
|
||||||
wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
|
wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION);
|
wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION);
|
||||||
wpabuf_put_u8(msg, WFA_ELEM_VERSION2);
|
wpabuf_put_u8(msg, WFA_ELEM_VERSION2);
|
||||||
wpabuf_put_u8(msg, 1);
|
wpabuf_put_u8(msg, 1);
|
||||||
wpabuf_put_u8(msg, WPS_VERSION);
|
wpabuf_put_u8(msg, WPS_VERSION);
|
||||||
|
|
||||||
if (req_to_enroll) {
|
if (req_to_enroll) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)");
|
wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)");
|
||||||
wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL);
|
wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL);
|
||||||
wpabuf_put_u8(msg, 1);
|
wpabuf_put_u8(msg, 1);
|
||||||
wpabuf_put_u8(msg, 1);
|
wpabuf_put_u8(msg, 1);
|
||||||
@@ -215,22 +244,31 @@ int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
|||||||
|
|
||||||
if (auth_macs && auth_macs_count) {
|
if (auth_macs && auth_macs_count) {
|
||||||
size_t i;
|
size_t i;
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)",
|
wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)",
|
||||||
(int) auth_macs_count);
|
(int) auth_macs_count);
|
||||||
wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS);
|
wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS);
|
||||||
wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN);
|
wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN);
|
||||||
wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN);
|
wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN);
|
||||||
for (i = 0; i < auth_macs_count; i++)
|
for (i = 0; i < auth_macs_count; i++)
|
||||||
wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR,
|
wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR,
|
||||||
MAC2STR(&auth_macs[i * ETH_ALEN]));
|
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);
|
WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_TESTING
|
#ifdef CONFIG_WPS_TESTING
|
||||||
if (WPS_VERSION > 0x20) {
|
if (WPS_VERSION > 0x20) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra "
|
if (wpabuf_tailroom(msg) < 5)
|
||||||
|
return -1;
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra "
|
||||||
"attribute");
|
"attribute");
|
||||||
wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST);
|
wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
@@ -243,7 +281,7 @@ int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
|||||||
|
|
||||||
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
|
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Message Type (%d)", msg_type);
|
wpa_printf(MSG_DEBUG, "WPS: * Message Type (%d)", msg_type);
|
||||||
wpabuf_put_be16(msg, ATTR_MSG_TYPE);
|
wpabuf_put_be16(msg, ATTR_MSG_TYPE);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
wpabuf_put_u8(msg, msg_type);
|
wpabuf_put_u8(msg, msg_type);
|
||||||
@@ -253,7 +291,7 @@ 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_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Enrollee Nonce");
|
wpa_printf(MSG_DEBUG, "WPS: * Enrollee Nonce");
|
||||||
wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
|
wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
|
||||||
wpabuf_put_be16(msg, WPS_NONCE_LEN);
|
wpabuf_put_be16(msg, WPS_NONCE_LEN);
|
||||||
wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
|
wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
|
||||||
@@ -263,7 +301,7 @@ int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
|
|
||||||
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
|
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Registrar Nonce");
|
wpa_printf(MSG_DEBUG, "WPS: * Registrar Nonce");
|
||||||
wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
|
wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
|
||||||
wpabuf_put_be16(msg, WPS_NONCE_LEN);
|
wpabuf_put_be16(msg, WPS_NONCE_LEN);
|
||||||
wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
|
wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
|
||||||
@@ -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)
|
int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
u16 auth_types = WPS_AUTH_TYPES;
|
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;
|
auth_types &= ~WPS_AUTH_SHARED;
|
||||||
#endif /* CONFIG_WPS2 */
|
#ifdef CONFIG_NO_TKIP
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags");
|
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, ATTR_AUTH_TYPE_FLAGS);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, auth_types);
|
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)
|
int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
u16 encr_types = WPS_ENCR_TYPES;
|
u16 encr_types = WPS_ENCR_TYPES;
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
encr_types &= ~WPS_ENCR_WEP;
|
encr_types &= ~WPS_ENCR_WEP;
|
||||||
#endif /* CONFIG_WPS2 */
|
#ifdef CONFIG_NO_TKIP
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags");
|
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, ATTR_ENCR_TYPE_FLAGS);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, encr_types);
|
wpabuf_put_be16(msg, encr_types);
|
||||||
@@ -301,7 +362,7 @@ int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
|
|
||||||
int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Connection Type Flags");
|
wpa_printf(MSG_DEBUG, "WPS: * Connection Type Flags");
|
||||||
wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
|
wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
|
||||||
wpabuf_put_be16(msg, 1);
|
wpabuf_put_be16(msg, 1);
|
||||||
wpabuf_put_u8(msg, WPS_CONN_ESS);
|
wpabuf_put_u8(msg, WPS_CONN_ESS);
|
||||||
@@ -311,7 +372,7 @@ int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
|
|
||||||
int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
|
int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Association State");
|
wpa_printf(MSG_DEBUG, "WPS: * Association State");
|
||||||
wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
|
wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
|
||||||
wpabuf_put_be16(msg, 2);
|
wpabuf_put_be16(msg, 2);
|
||||||
wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
|
wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
|
||||||
@@ -323,9 +384,11 @@ int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
|
|||||||
{
|
{
|
||||||
u8 hash[SHA256_MAC_LEN];
|
u8 hash[SHA256_MAC_LEN];
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator");
|
wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator");
|
||||||
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
|
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
|
||||||
wpabuf_len(msg), hash);
|
wpabuf_len(msg), hash) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
|
wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
|
||||||
wpabuf_put_be16(msg, WPS_KWA_LEN);
|
wpabuf_put_be16(msg, WPS_KWA_LEN);
|
||||||
wpabuf_put_data(msg, hash, WPS_KWA_LEN);
|
wpabuf_put_data(msg, hash, WPS_KWA_LEN);
|
||||||
@@ -340,7 +403,7 @@ int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
|
|||||||
const size_t block_size = 16;
|
const size_t block_size = 16;
|
||||||
u8 *iv, *data;
|
u8 *iv, *data;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings");
|
wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings");
|
||||||
|
|
||||||
/* PKCS#5 v2.0 pad */
|
/* PKCS#5 v2.0 pad */
|
||||||
pad_len = block_size - wpabuf_len(plain) % block_size;
|
pad_len = block_size - wpabuf_len(plain) % block_size;
|
||||||
@@ -355,9 +418,9 @@ int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
|
|||||||
|
|
||||||
data = wpabuf_put(msg, 0);
|
data = wpabuf_put(msg, 0);
|
||||||
wpabuf_put_buf(msg, plain);
|
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)))
|
if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,14 +434,32 @@ int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id,
|
|||||||
const u8 *addr[1];
|
const u8 *addr[1];
|
||||||
u8 pubkey_hash[WPS_HASH_LEN];
|
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);
|
addr[0] = wpabuf_head(pubkey);
|
||||||
hash_len = wpabuf_len(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, ATTR_OOB_DEVICE_PASSWORD);
|
||||||
wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len);
|
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_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
|
||||||
wpabuf_put_be16(msg, dev_pw_id);
|
wpabuf_put_be16(msg, dev_pw_id);
|
||||||
wpabuf_put_data(msg, dev_pw, dev_pw_len);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -415,3 +496,34 @@ struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
|
|||||||
|
|
||||||
return ie;
|
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;
|
||||||
|
}
|
||||||
|
@@ -5,11 +5,12 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "includes.h"
|
||||||
#include "wps/wps_defs.h"
|
|
||||||
#include "wps/wps_attr_parse.h"
|
#include "common.h"
|
||||||
|
#include "wps_defs.h"
|
||||||
|
#include "wps_attr_parse.h"
|
||||||
|
|
||||||
#ifndef CONFIG_WPS_STRICT
|
#ifndef CONFIG_WPS_STRICT
|
||||||
#define WPS_WORKAROUNDS
|
#define WPS_WORKAROUNDS
|
||||||
@@ -19,12 +20,12 @@
|
|||||||
static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
||||||
u8 id, u8 len, const u8 *pos)
|
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);
|
id, len);
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case WFA_ELEM_VERSION2:
|
case WFA_ELEM_VERSION2:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -36,7 +37,7 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
|||||||
break;
|
break;
|
||||||
case WFA_ELEM_NETWORK_KEY_SHAREABLE:
|
case WFA_ELEM_NETWORK_KEY_SHAREABLE:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
|
||||||
"Shareable length %u", len);
|
"Shareable length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -44,7 +45,7 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
|||||||
break;
|
break;
|
||||||
case WFA_ELEM_REQUEST_TO_ENROLL:
|
case WFA_ELEM_REQUEST_TO_ENROLL:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -52,14 +53,33 @@ static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
|
|||||||
break;
|
break;
|
||||||
case WFA_ELEM_SETTINGS_DELAY_TIME:
|
case WFA_ELEM_SETTINGS_DELAY_TIME:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
|
||||||
"Time length %u", len);
|
"Time length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
attr->settings_delay_time = pos;
|
attr->settings_delay_time = pos;
|
||||||
break;
|
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:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Skipped unknown WFA Vendor "
|
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
|
||||||
"Extension subelement %u", id);
|
"Extension subelement %u", id);
|
||||||
break;
|
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;
|
const u8 *end = pos + len;
|
||||||
u8 id, elen;
|
u8 id, elen;
|
||||||
|
|
||||||
while (pos + 2 < end) {
|
while (end - pos >= 2) {
|
||||||
id = *pos++;
|
id = *pos++;
|
||||||
elen = *pos++;
|
elen = *pos++;
|
||||||
if (pos + elen > end)
|
if (elen > end - pos)
|
||||||
break;
|
break;
|
||||||
if (wps_set_vendor_ext_wfa_subelem(attr, id, elen, pos) < 0)
|
if (wps_set_vendor_ext_wfa_subelem(attr, id, elen, pos) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -94,7 +114,7 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
|
|||||||
u32 vendor_id;
|
u32 vendor_id;
|
||||||
|
|
||||||
if (len < 3) {
|
if (len < 3) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Skip invalid Vendor Extension");
|
wpa_printf(MSG_DEBUG, "WPS: Skip invalid Vendor Extension");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,17 +126,17 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
|
|||||||
|
|
||||||
/* Handle unknown vendor extensions */
|
/* 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);
|
vendor_id);
|
||||||
|
|
||||||
if (len > WPS_MAX_VENDOR_EXT_LEN) {
|
if (len > WPS_MAX_VENDOR_EXT_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Too long Vendor Extension (%u)",
|
wpa_printf(MSG_DEBUG, "WPS: Too long Vendor Extension (%u)",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->num_vendor_ext >= MAX_WPS_PARSE_VENDOR_EXT) {
|
if (attr->num_vendor_ext >= MAX_WPS_PARSE_VENDOR_EXT) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Skipped Vendor Extension "
|
wpa_printf(MSG_DEBUG, "WPS: Skipped Vendor Extension "
|
||||||
"attribute (max %d vendor extensions)",
|
"attribute (max %d vendor extensions)",
|
||||||
MAX_WPS_PARSE_VENDOR_EXT);
|
MAX_WPS_PARSE_VENDOR_EXT);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -128,13 +148,14 @@ static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
||||||
const u8 *pos, u16 len)
|
const u8 *pos, u16 len)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ATTR_VERSION:
|
case ATTR_VERSION:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -142,7 +163,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_MSG_TYPE:
|
case ATTR_MSG_TYPE:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -150,7 +171,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_ENROLLEE_NONCE:
|
case ATTR_ENROLLEE_NONCE:
|
||||||
if (len != WPS_NONCE_LEN) {
|
if (len != WPS_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -158,7 +179,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_REGISTRAR_NONCE:
|
case ATTR_REGISTRAR_NONCE:
|
||||||
if (len != WPS_NONCE_LEN) {
|
if (len != WPS_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -166,7 +187,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_UUID_E:
|
case ATTR_UUID_E:
|
||||||
if (len != WPS_UUID_LEN) {
|
if (len != WPS_UUID_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -174,7 +195,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_UUID_R:
|
case ATTR_UUID_R:
|
||||||
if (len != WPS_UUID_LEN) {
|
if (len != WPS_UUID_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -182,7 +203,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_AUTH_TYPE_FLAGS:
|
case ATTR_AUTH_TYPE_FLAGS:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
|
||||||
"Type Flags length %u", len);
|
"Type Flags length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -190,7 +211,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_ENCR_TYPE_FLAGS:
|
case ATTR_ENCR_TYPE_FLAGS:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
|
||||||
"Flags length %u", len);
|
"Flags length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -198,7 +219,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_CONN_TYPE_FLAGS:
|
case ATTR_CONN_TYPE_FLAGS:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
|
||||||
"Flags length %u", len);
|
"Flags length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -206,7 +227,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_CONFIG_METHODS:
|
case ATTR_CONFIG_METHODS:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -214,7 +235,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
|
case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
|
||||||
"Registrar Config Methods length %u", len);
|
"Registrar Config Methods length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -222,7 +243,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_PRIMARY_DEV_TYPE:
|
case ATTR_PRIMARY_DEV_TYPE:
|
||||||
if (len != WPS_DEV_TYPE_LEN) {
|
if (len != WPS_DEV_TYPE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
|
||||||
"Type length %u", len);
|
"Type length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -230,7 +251,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_RF_BANDS:
|
case ATTR_RF_BANDS:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -238,7 +259,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_ASSOC_STATE:
|
case ATTR_ASSOC_STATE:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -246,7 +267,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_CONFIG_ERROR:
|
case ATTR_CONFIG_ERROR:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
|
||||||
"Error length %u", len);
|
"Error length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -254,18 +275,21 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_DEV_PASSWORD_ID:
|
case ATTR_DEV_PASSWORD_ID:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
|
||||||
"ID length %u", len);
|
"ID length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
attr->dev_password_id = pos;
|
attr->dev_password_id = pos;
|
||||||
break;
|
break;
|
||||||
case ATTR_OOB_DEVICE_PASSWORD:
|
case ATTR_OOB_DEVICE_PASSWORD:
|
||||||
if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
|
if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
|
||||||
WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
|
|
||||||
len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
|
len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
|
||||||
WPS_OOB_DEVICE_PASSWORD_LEN) {
|
WPS_OOB_DEVICE_PASSWORD_LEN ||
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
|
(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);
|
"Password length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -274,7 +298,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_OS_VERSION:
|
case ATTR_OS_VERSION:
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -282,7 +306,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_WPS_STATE:
|
case ATTR_WPS_STATE:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
|
||||||
"Setup State length %u", len);
|
"Setup State length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -290,7 +314,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_AUTHENTICATOR:
|
case ATTR_AUTHENTICATOR:
|
||||||
if (len != WPS_AUTHENTICATOR_LEN) {
|
if (len != WPS_AUTHENTICATOR_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -298,7 +322,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_R_HASH1:
|
case ATTR_R_HASH1:
|
||||||
if (len != WPS_HASH_LEN) {
|
if (len != WPS_HASH_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -306,7 +330,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_R_HASH2:
|
case ATTR_R_HASH2:
|
||||||
if (len != WPS_HASH_LEN) {
|
if (len != WPS_HASH_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -314,7 +338,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_E_HASH1:
|
case ATTR_E_HASH1:
|
||||||
if (len != WPS_HASH_LEN) {
|
if (len != WPS_HASH_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -322,7 +346,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_E_HASH2:
|
case ATTR_E_HASH2:
|
||||||
if (len != WPS_HASH_LEN) {
|
if (len != WPS_HASH_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
|
wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
|
||||||
len);
|
len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -330,7 +354,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_R_SNONCE1:
|
case ATTR_R_SNONCE1:
|
||||||
if (len != WPS_SECRET_NONCE_LEN) {
|
if (len != WPS_SECRET_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -338,7 +362,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_R_SNONCE2:
|
case ATTR_R_SNONCE2:
|
||||||
if (len != WPS_SECRET_NONCE_LEN) {
|
if (len != WPS_SECRET_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -346,7 +370,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_E_SNONCE1:
|
case ATTR_E_SNONCE1:
|
||||||
if (len != WPS_SECRET_NONCE_LEN) {
|
if (len != WPS_SECRET_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -354,7 +378,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_E_SNONCE2:
|
case ATTR_E_SNONCE2:
|
||||||
if (len != WPS_SECRET_NONCE_LEN) {
|
if (len != WPS_SECRET_NONCE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
|
||||||
"%u", len);
|
"%u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -362,7 +386,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_KEY_WRAP_AUTH:
|
case ATTR_KEY_WRAP_AUTH:
|
||||||
if (len != WPS_KWA_LEN) {
|
if (len != WPS_KWA_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
|
||||||
"Authenticator length %u", len);
|
"Authenticator length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -370,7 +394,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_AUTH_TYPE:
|
case ATTR_AUTH_TYPE:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
|
||||||
"Type length %u", len);
|
"Type length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -378,7 +402,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_ENCR_TYPE:
|
case ATTR_ENCR_TYPE:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
|
||||||
"Type length %u", len);
|
"Type length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -386,7 +410,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_NETWORK_INDEX:
|
case ATTR_NETWORK_INDEX:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -394,7 +418,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_NETWORK_KEY_INDEX:
|
case ATTR_NETWORK_KEY_INDEX:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -402,31 +426,15 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_MAC_ADDR:
|
case ATTR_MAC_ADDR:
|
||||||
if (len != ETH_ALEN) {
|
if (len != ETH_ALEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
attr->mac_addr = pos;
|
attr->mac_addr = pos;
|
||||||
break;
|
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:
|
case ATTR_SELECTED_REGISTRAR:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
|
||||||
" length %u", len);
|
" length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -434,7 +442,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_REQUEST_TYPE:
|
case ATTR_REQUEST_TYPE:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -442,7 +450,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_RESPONSE_TYPE:
|
case ATTR_RESPONSE_TYPE:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -450,25 +458,55 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_MANUFACTURER:
|
case ATTR_MANUFACTURER:
|
||||||
attr->manufacturer = pos;
|
attr->manufacturer = pos;
|
||||||
attr->manufacturer_len = len;
|
if (len > WPS_MANUFACTURER_MAX_LEN)
|
||||||
|
attr->manufacturer_len = WPS_MANUFACTURER_MAX_LEN;
|
||||||
|
else
|
||||||
|
attr->manufacturer_len = len;
|
||||||
break;
|
break;
|
||||||
case ATTR_MODEL_NAME:
|
case ATTR_MODEL_NAME:
|
||||||
attr->model_name = pos;
|
attr->model_name = pos;
|
||||||
attr->model_name_len = len;
|
if (len > WPS_MODEL_NAME_MAX_LEN)
|
||||||
|
attr->model_name_len = WPS_MODEL_NAME_MAX_LEN;
|
||||||
|
else
|
||||||
|
attr->model_name_len = len;
|
||||||
break;
|
break;
|
||||||
case ATTR_MODEL_NUMBER:
|
case ATTR_MODEL_NUMBER:
|
||||||
attr->model_number = pos;
|
attr->model_number = pos;
|
||||||
attr->model_number_len = len;
|
if (len > WPS_MODEL_NUMBER_MAX_LEN)
|
||||||
|
attr->model_number_len = WPS_MODEL_NUMBER_MAX_LEN;
|
||||||
|
else
|
||||||
|
attr->model_number_len = len;
|
||||||
break;
|
break;
|
||||||
case ATTR_SERIAL_NUMBER:
|
case ATTR_SERIAL_NUMBER:
|
||||||
attr->serial_number = pos;
|
attr->serial_number = pos;
|
||||||
attr->serial_number_len = len;
|
if (len > WPS_SERIAL_NUMBER_MAX_LEN)
|
||||||
|
attr->serial_number_len = WPS_SERIAL_NUMBER_MAX_LEN;
|
||||||
|
else
|
||||||
|
attr->serial_number_len = len;
|
||||||
break;
|
break;
|
||||||
case ATTR_DEV_NAME:
|
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 = pos;
|
||||||
attr->dev_name_len = len;
|
attr->dev_name_len = len;
|
||||||
break;
|
break;
|
||||||
case ATTR_PUBLIC_KEY:
|
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 = pos;
|
||||||
attr->public_key_len = len;
|
attr->public_key_len = len;
|
||||||
break;
|
break;
|
||||||
@@ -478,7 +516,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_CRED:
|
case ATTR_CRED:
|
||||||
if (attr->num_cred >= MAX_CRED_COUNT) {
|
if (attr->num_cred >= MAX_CRED_COUNT) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
|
wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
|
||||||
"attribute (max %d credentials)",
|
"attribute (max %d credentials)",
|
||||||
MAX_CRED_COUNT);
|
MAX_CRED_COUNT);
|
||||||
break;
|
break;
|
||||||
@@ -488,6 +526,11 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
attr->num_cred++;
|
attr->num_cred++;
|
||||||
break;
|
break;
|
||||||
case ATTR_SSID:
|
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 = pos;
|
||||||
attr->ssid_len = len;
|
attr->ssid_len = len;
|
||||||
break;
|
break;
|
||||||
@@ -495,17 +538,9 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
attr->network_key = pos;
|
attr->network_key = pos;
|
||||||
attr->network_key_len = len;
|
attr->network_key_len = len;
|
||||||
break;
|
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:
|
case ATTR_AP_SETUP_LOCKED:
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -513,12 +548,12 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_REQUESTED_DEV_TYPE:
|
case ATTR_REQUESTED_DEV_TYPE:
|
||||||
if (len != WPS_DEV_TYPE_LEN) {
|
if (len != WPS_DEV_TYPE_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device "
|
||||||
"Type length %u", len);
|
"Type length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (attr->num_req_dev_type >= MAX_REQ_DEV_TYPE_COUNT) {
|
if (attr->num_req_dev_type >= MAX_REQ_DEV_TYPE_COUNT) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Skipped Requested Device "
|
wpa_printf(MSG_DEBUG, "WPS: Skipped Requested Device "
|
||||||
"Type attribute (max %u types)",
|
"Type attribute (max %u types)",
|
||||||
MAX_REQ_DEV_TYPE_COUNT);
|
MAX_REQ_DEV_TYPE_COUNT);
|
||||||
break;
|
break;
|
||||||
@@ -529,7 +564,7 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
case ATTR_SECONDARY_DEV_TYPE_LIST:
|
case ATTR_SECONDARY_DEV_TYPE_LIST:
|
||||||
if (len > WPS_SEC_DEV_TYPE_MAX_LEN ||
|
if (len > WPS_SEC_DEV_TYPE_MAX_LEN ||
|
||||||
(len % WPS_DEV_TYPE_LEN) > 0) {
|
(len % WPS_DEV_TYPE_LEN) > 0) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid Secondary Device "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid Secondary Device "
|
||||||
"Type length %u", len);
|
"Type length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -542,14 +577,14 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
|
|||||||
break;
|
break;
|
||||||
case ATTR_AP_CHANNEL:
|
case ATTR_AP_CHANNEL:
|
||||||
if (len != 2) {
|
if (len != 2) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid AP Channel "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid AP Channel "
|
||||||
"length %u", len);
|
"length %u", len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
attr->ap_channel = pos;
|
attr->ap_channel = pos;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
|
wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
|
||||||
"len=%u", type, len);
|
"len=%u", type, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -572,7 +607,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
|||||||
|
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
if (end - pos < 4) {
|
if (end - pos < 4) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
|
||||||
"%lu bytes remaining",
|
"%lu bytes remaining",
|
||||||
(unsigned long) (end - pos));
|
(unsigned long) (end - pos));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -582,10 +617,10 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
|||||||
pos += 2;
|
pos += 2;
|
||||||
len = WPA_GET_BE16(pos);
|
len = WPA_GET_BE16(pos);
|
||||||
pos += 2;
|
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);
|
type, len);
|
||||||
if (len > end - pos) {
|
if (len > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
|
wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
|
||||||
wpa_hexdump_buf(MSG_MSGDUMP, "WPS: Message data", msg);
|
wpa_hexdump_buf(MSG_MSGDUMP, "WPS: Message data", msg);
|
||||||
#ifdef WPS_WORKAROUNDS
|
#ifdef WPS_WORKAROUNDS
|
||||||
/*
|
/*
|
||||||
@@ -597,7 +632,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
|||||||
*/
|
*/
|
||||||
if ((type & 0xff00) != 0x1000 &&
|
if ((type & 0xff00) != 0x1000 &&
|
||||||
prev_type == ATTR_NETWORK_KEY) {
|
prev_type == ATTR_NETWORK_KEY) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Workaround - try "
|
wpa_printf(MSG_DEBUG, "WPS: Workaround - try "
|
||||||
"to skip unexpected octet after "
|
"to skip unexpected octet after "
|
||||||
"Network Key");
|
"Network Key");
|
||||||
pos -= 3;
|
pos -= 3;
|
||||||
@@ -619,7 +654,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == end - pos) {
|
if (i == end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
|
wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
|
||||||
"unexpected message padding");
|
"unexpected message padding");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#ifndef WPS_ATTR_PARSE_H
|
#ifndef WPS_ATTR_PARSE_H
|
||||||
#define WPS_ATTR_PARSE_H
|
#define WPS_ATTR_PARSE_H
|
||||||
|
|
||||||
#include "wps/wps.h"
|
#include "wps.h"
|
||||||
|
|
||||||
struct wps_parse_attr {
|
struct wps_parse_attr {
|
||||||
/* fixed length fields */
|
/* fixed length fields */
|
||||||
@@ -47,8 +47,6 @@ struct wps_parse_attr {
|
|||||||
const u8 *network_idx; /* 1 octet */
|
const u8 *network_idx; /* 1 octet */
|
||||||
const u8 *network_key_idx; /* 1 octet */
|
const u8 *network_key_idx; /* 1 octet */
|
||||||
const u8 *mac_addr; /* ETH_ALEN (6) octets */
|
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 *selected_registrar; /* 1 octet (Bool) */
|
||||||
const u8 *request_type; /* 1 octet */
|
const u8 *request_type; /* 1 octet */
|
||||||
const u8 *response_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 *network_key_shareable; /* 1 octet (Bool) */
|
||||||
const u8 *request_to_enroll; /* 1 octet (Bool) */
|
const u8 *request_to_enroll; /* 1 octet (Bool) */
|
||||||
const u8 *ap_channel; /* 2 octets */
|
const u8 *ap_channel; /* 2 octets */
|
||||||
|
const u8 *registrar_configuration_methods; /* 2 octets */
|
||||||
|
|
||||||
/* variable length fields */
|
/* variable length fields */
|
||||||
const u8 *manufacturer;
|
const u8 *manufacturer;
|
||||||
size_t manufacturer_len;
|
|
||||||
const u8 *model_name;
|
const u8 *model_name;
|
||||||
size_t model_name_len;
|
|
||||||
const u8 *model_number;
|
const u8 *model_number;
|
||||||
size_t model_number_len;
|
|
||||||
const u8 *serial_number;
|
const u8 *serial_number;
|
||||||
size_t serial_number_len;
|
|
||||||
const u8 *dev_name;
|
const u8 *dev_name;
|
||||||
size_t dev_name_len;
|
|
||||||
const u8 *public_key;
|
const u8 *public_key;
|
||||||
size_t public_key_len;
|
|
||||||
const u8 *encr_settings;
|
const u8 *encr_settings;
|
||||||
size_t encr_settings_len;
|
|
||||||
const u8 *ssid; /* <= 32 octets */
|
const u8 *ssid; /* <= 32 octets */
|
||||||
size_t ssid_len;
|
|
||||||
const u8 *network_key; /* <= 64 octets */
|
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 */
|
const u8 *authorized_macs; /* <= 30 octets */
|
||||||
size_t authorized_macs_len;
|
|
||||||
const u8 *sec_dev_type_list; /* <= 128 octets */
|
const u8 *sec_dev_type_list; /* <= 128 octets */
|
||||||
size_t sec_dev_type_list_len;
|
|
||||||
const u8 *oob_dev_password; /* 38..54 octets */
|
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 */
|
/* attributes that can occur multiple times */
|
||||||
#define MAX_CRED_COUNT 10
|
#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
|
#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];
|
const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
|
||||||
size_t vendor_ext_len[MAX_WPS_PARSE_VENDOR_EXT];
|
u8 multi_ap_ext;
|
||||||
size_t num_vendor_ext;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
||||||
|
@@ -5,11 +5,12 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
#include "utils/includes.h"
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "crypto/sha256.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,
|
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
|
||||||
@@ -20,13 +21,13 @@ int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
|
|||||||
size_t len[2];
|
size_t len[2];
|
||||||
|
|
||||||
if (authenticator == NULL) {
|
if (authenticator == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
|
wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
|
||||||
"included");
|
"included");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wps->last_msg == NULL) {
|
if (wps->last_msg == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
|
wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
|
||||||
"validating authenticator");
|
"validating authenticator");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -38,9 +39,11 @@ int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
|
|||||||
len[0] = wpabuf_len(wps->last_msg);
|
len[0] = wpabuf_len(wps->last_msg);
|
||||||
addr[1] = wpabuf_head(msg);
|
addr[1] = wpabuf_head(msg);
|
||||||
len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
|
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,
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
|
hash) < 0 ||
|
||||||
|
os_memcmp_const(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,21 +59,21 @@ int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (key_wrap_auth == NULL) {
|
if (key_wrap_auth == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
|
wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
head = wpabuf_head(msg);
|
head = wpabuf_head(msg);
|
||||||
len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
|
len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
|
||||||
if (head + len != key_wrap_auth - 4) {
|
if (head + len != key_wrap_auth - 4) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
|
wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
|
||||||
"decrypted attribute");
|
"decrypted attribute");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
|
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash) < 0 ||
|
||||||
if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
|
os_memcmp_const(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
|
wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +85,12 @@ static int wps_process_cred_network_idx(struct wps_credential *cred,
|
|||||||
const u8 *idx)
|
const u8 *idx)
|
||||||
{
|
{
|
||||||
if (idx == NULL) {
|
if (idx == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
||||||
"Network Index");
|
"Network Index");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
|
wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -97,7 +100,7 @@ static int wps_process_cred_ssid(struct wps_credential *cred, const u8 *ssid,
|
|||||||
size_t ssid_len)
|
size_t ssid_len)
|
||||||
{
|
{
|
||||||
if (ssid == NULL) {
|
if (ssid == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,13 +123,13 @@ static int wps_process_cred_auth_type(struct wps_credential *cred,
|
|||||||
const u8 *auth_type)
|
const u8 *auth_type)
|
||||||
{
|
{
|
||||||
if (auth_type == NULL) {
|
if (auth_type == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
||||||
"Authentication Type");
|
"Authentication Type");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cred->auth_type = WPA_GET_BE16(auth_type);
|
cred->auth_type = WPA_GET_BE16(auth_type);
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
|
wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
|
||||||
cred->auth_type);
|
cred->auth_type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -137,13 +140,13 @@ static int wps_process_cred_encr_type(struct wps_credential *cred,
|
|||||||
const u8 *encr_type)
|
const u8 *encr_type)
|
||||||
{
|
{
|
||||||
if (encr_type == NULL) {
|
if (encr_type == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
||||||
"Encryption Type");
|
"Encryption Type");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cred->encr_type = WPA_GET_BE16(encr_type);
|
cred->encr_type = WPA_GET_BE16(encr_type);
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
|
wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
|
||||||
cred->encr_type);
|
cred->encr_type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -156,7 +159,7 @@ static int wps_process_cred_network_key_idx(struct wps_credential *cred,
|
|||||||
if (key_idx == NULL)
|
if (key_idx == NULL)
|
||||||
return 0; /* optional attribute */
|
return 0; /* optional attribute */
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
|
wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
|
||||||
cred->key_idx = *key_idx;
|
cred->key_idx = *key_idx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -167,11 +170,11 @@ static int wps_process_cred_network_key(struct wps_credential *cred,
|
|||||||
const u8 *key, size_t key_len)
|
const u8 *key, size_t key_len)
|
||||||
{
|
{
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
||||||
"Network Key");
|
"Network Key");
|
||||||
if (cred->auth_type == WPS_WIFI_AUTH_OPEN &&
|
if (cred->auth_type == WPS_AUTH_OPEN &&
|
||||||
cred->encr_type == WPS_ENCR_NONE) {
|
cred->encr_type == WPS_ENCR_NONE) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Workaround - Allow "
|
wpa_printf(MSG_DEBUG, "WPS: Workaround - Allow "
|
||||||
"missing mandatory Network Key attribute "
|
"missing mandatory Network Key attribute "
|
||||||
"for open network");
|
"for open network");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -193,82 +196,18 @@ static int wps_process_cred_mac_addr(struct wps_credential *cred,
|
|||||||
const u8 *mac_addr)
|
const u8 *mac_addr)
|
||||||
{
|
{
|
||||||
if (mac_addr == NULL) {
|
if (mac_addr == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
|
||||||
"MAC Address");
|
"MAC Address");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
|
wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
|
||||||
os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
|
os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
static int wps_workaround_cred_key(struct wps_credential *cred)
|
||||||
{
|
{
|
||||||
if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
|
if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
|
||||||
@@ -286,11 +225,21 @@ static int wps_workaround_cred_key(struct wps_credential *cred)
|
|||||||
* passphrases incorrectly. Remove the extra NULL termination
|
* passphrases incorrectly. Remove the extra NULL termination
|
||||||
* to fix the encoding.
|
* to fix the encoding.
|
||||||
*/
|
*/
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Workaround - remove NULL "
|
wpa_printf(MSG_DEBUG, "WPS: Workaround - remove NULL "
|
||||||
"termination from ASCII passphrase");
|
"termination from ASCII passphrase");
|
||||||
cred->key_len--;
|
cred->key_len--;
|
||||||
#endif /* CONFIG_WPS_STRICT */
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +247,7 @@ static int wps_workaround_cred_key(struct wps_credential *cred)
|
|||||||
int wps_process_cred(struct wps_parse_attr *attr,
|
int wps_process_cred(struct wps_parse_attr *attr,
|
||||||
struct wps_credential *cred)
|
struct wps_credential *cred)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Process Credential");
|
wpa_printf(MSG_DEBUG, "WPS: Process Credential");
|
||||||
|
|
||||||
/* TODO: support multiple Network Keys */
|
/* TODO: support multiple Network Keys */
|
||||||
if (wps_process_cred_network_idx(cred, attr->network_idx) ||
|
if (wps_process_cred_network_idx(cred, attr->network_idx) ||
|
||||||
@@ -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_idx(cred, attr->network_key_idx) ||
|
||||||
wps_process_cred_network_key(cred, attr->network_key,
|
wps_process_cred_network_key(cred, attr->network_key,
|
||||||
attr->network_key_len) ||
|
attr->network_key_len) ||
|
||||||
wps_process_cred_mac_addr(cred, attr->mac_addr) ||
|
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))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return wps_workaround_cred_key(cred);
|
return wps_workaround_cred_key(cred);
|
||||||
@@ -325,7 +267,7 @@ int wps_process_cred(struct wps_parse_attr *attr,
|
|||||||
int wps_process_ap_settings(struct wps_parse_attr *attr,
|
int wps_process_ap_settings(struct wps_parse_attr *attr,
|
||||||
struct wps_credential *cred)
|
struct wps_credential *cred)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
|
wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
|
||||||
os_memset(cred, 0, sizeof(*cred));
|
os_memset(cred, 0, sizeof(*cred));
|
||||||
/* TODO: optional attributes New Password and Device Password ID */
|
/* TODO: optional attributes New Password and Device Password ID */
|
||||||
if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
|
if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
|
||||||
|
@@ -5,19 +5,21 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "includes.h"
|
||||||
#include "utils/common.h"
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "common/defs.h"
|
||||||
|
#include "common/ieee802_11_common.h"
|
||||||
#include "crypto/aes_wrap.h"
|
#include "crypto/aes_wrap.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
|
#include "crypto/dh_group5.h"
|
||||||
#include "crypto/sha1.h"
|
#include "crypto/sha1.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
#include "crypto/dh_group5.h"
|
|
||||||
#include "crypto/random.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,
|
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
|
||||||
const char *label, u8 *res, size_t res_len)
|
const char *label, u8 *res, size_t res_len)
|
||||||
@@ -66,13 +68,13 @@ int wps_derive_keys(struct wps_data *wps)
|
|||||||
u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN];
|
u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN];
|
||||||
|
|
||||||
if (wps->dh_privkey == NULL) {
|
if (wps->dh_privkey == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available");
|
wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r;
|
pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r;
|
||||||
if (pubkey == NULL) {
|
if (pubkey == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available");
|
wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,17 +85,17 @@ int wps_derive_keys(struct wps_data *wps)
|
|||||||
wps->dh_ctx = NULL;
|
wps->dh_ctx = NULL;
|
||||||
dh_shared = wpabuf_zeropad(dh_shared, 192);
|
dh_shared = wpabuf_zeropad(dh_shared, 192);
|
||||||
if (dh_shared == NULL) {
|
if (dh_shared == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
|
wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Own DH private key is not needed anymore */
|
/* 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
|
* 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 .
|
* which would cause WPS fail, so we clean the key after WPS finished .
|
||||||
*/
|
*/
|
||||||
#ifndef ESP32_WORKAROUND
|
#ifndef ESP32_WORKAROUND
|
||||||
wpabuf_free(wps->dh_privkey);
|
wpabuf_clear_free(wps->dh_privkey);
|
||||||
wps->dh_privkey = NULL;
|
wps->dh_privkey = NULL;
|
||||||
#endif //ESP32_WORKAROUND
|
#endif //ESP32_WORKAROUND
|
||||||
|
|
||||||
@@ -102,10 +104,9 @@ int wps_derive_keys(struct wps_data *wps)
|
|||||||
/* DHKey = SHA-256(g^AB mod p) */
|
/* DHKey = SHA-256(g^AB mod p) */
|
||||||
addr[0] = wpabuf_head(dh_shared);
|
addr[0] = wpabuf_head(dh_shared);
|
||||||
len[0] = wpabuf_len(dh_shared);
|
len[0] = wpabuf_len(dh_shared);
|
||||||
|
|
||||||
sha256_vector(1, addr, len, dhkey);
|
sha256_vector(1, addr, len, dhkey);
|
||||||
wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(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) */
|
/* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
|
||||||
addr[0] = wps->nonce_e;
|
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)
|
size_t dev_passwd_len)
|
||||||
{
|
{
|
||||||
u8 hash[SHA256_MAC_LEN];
|
u8 hash[SHA256_MAC_LEN];
|
||||||
|
|
||||||
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
|
if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
|
||||||
(dev_passwd_len + 1) / 2, hash);
|
(dev_passwd_len + 1) / 2, hash) < 0)
|
||||||
|
return -1;
|
||||||
os_memcpy(wps->psk1, hash, WPS_PSK_LEN);
|
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 + (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);
|
os_memcpy(wps->psk2, hash, WPS_PSK_LEN);
|
||||||
|
|
||||||
wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password",
|
wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password",
|
||||||
dev_passwd, dev_passwd_len);
|
dev_passwd, dev_passwd_len);
|
||||||
wpa_hexdump_key(MSG_DEBUG, "WPS: PSK1", wps->psk1, WPS_PSK_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);
|
wpa_hexdump_key(MSG_DEBUG, "WPS: PSK2", wps->psk2, WPS_PSK_LEN);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -166,7 +170,7 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
|||||||
/* AES-128-CBC */
|
/* AES-128-CBC */
|
||||||
if (encr == NULL || encr_len < 2 * block_size || encr_len % block_size)
|
if (encr == NULL || encr_len < 2 * block_size || encr_len % block_size)
|
||||||
{
|
{
|
||||||
wpa_printf(MSG_DEBUG, "WPS: No Encrypted Settings received");
|
wpa_printf(MSG_DEBUG, "WPS: No Encrypted Settings received");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len);
|
||||||
wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size);
|
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),
|
if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
|
||||||
wpabuf_len(decrypted))) {
|
wpabuf_len(decrypted))) {
|
||||||
wpabuf_free(decrypted);
|
wpabuf_clear_free(decrypted);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,15 +192,15 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
|||||||
pos = wpabuf_head_u8(decrypted) + wpabuf_len(decrypted) - 1;
|
pos = wpabuf_head_u8(decrypted) + wpabuf_len(decrypted) - 1;
|
||||||
pad = *pos;
|
pad = *pos;
|
||||||
if (pad > wpabuf_len(decrypted)) {
|
if (pad > wpabuf_len(decrypted)) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value");
|
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value");
|
||||||
wpabuf_free(decrypted);
|
wpabuf_clear_free(decrypted);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < pad; i++) {
|
for (i = 0; i < pad; i++) {
|
||||||
if (*pos-- != pad) {
|
if (*pos-- != pad) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad "
|
wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad "
|
||||||
"string");
|
"string");
|
||||||
wpabuf_free(decrypted);
|
wpabuf_clear_free(decrypted);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +209,7 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
|||||||
return decrypted;
|
return decrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_PIN
|
|
||||||
/**
|
/**
|
||||||
* wps_pin_checksum - Compute PIN checksum
|
* wps_pin_checksum - Compute PIN checksum
|
||||||
* @pin: Seven digit PIN (i.e., eight digit PIN without the checksum digit)
|
* @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
|
* wps_generate_pin - Generate a random PIN
|
||||||
* Returns: Eight digit PIN (i.e., including the checksum digit)
|
* 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;
|
unsigned int val;
|
||||||
|
|
||||||
/* Generate seven random digits for the PIN */
|
/* 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;
|
return -1;
|
||||||
}
|
|
||||||
val %= 10000000;
|
val %= 10000000;
|
||||||
|
|
||||||
/* Append checksum digit */
|
/* 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;
|
len = p - pin;
|
||||||
return len == 4 || len == 8;
|
return len == 4 || len == 8;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
|
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)
|
if (wps->event_cb == NULL)
|
||||||
return;
|
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 (wps->event_cb == NULL)
|
||||||
if (data == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wps->event_cb == NULL) {
|
os_memset(&data, 0, sizeof(data));
|
||||||
os_free(data);
|
os_memcpy(data.success.peer_macaddr, mac_addr, ETH_ALEN);
|
||||||
return;
|
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;
|
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part,
|
||||||
data->pwd_auth_fail.part = part;
|
const u8 *mac_addr)
|
||||||
wps->event_cb(wps->cb_ctx, WPS_EV_PWD_AUTH_FAIL, data);
|
{
|
||||||
os_free(data);
|
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
|
#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;
|
struct wpabuf *plain;
|
||||||
|
|
||||||
data = (struct wps_data *)os_zalloc(sizeof(struct wps_data));
|
|
||||||
if (data == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
plain = wpabuf_alloc(500);
|
plain = wpabuf_alloc(500);
|
||||||
if (plain == NULL) {
|
if (plain == NULL) {
|
||||||
os_free(data);
|
wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
|
||||||
wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
|
|
||||||
"credential");
|
"credential");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_memset(data, 0, sizeof(struct wps_data));
|
os_memset(&data, 0, sizeof(data));
|
||||||
data->wps = wps;
|
data.wps = wps;
|
||||||
data->auth_type = wps->auth_types;
|
data.auth_type = wps->auth_types;
|
||||||
data->encr_type = wps->encr_types;
|
data.encr_type = wps->encr_types;
|
||||||
if (wps_build_version(plain) ||
|
if (wps_build_cred(&data, plain) ||
|
||||||
wps_build_cred(data, plain) ||
|
(rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
|
||||||
wps_build_wfa_ext(plain, 0, NULL, 0)) {
|
(channel && wps_build_ap_channel(plain, channel)) ||
|
||||||
wpabuf_free(plain);
|
wps_build_mac_addr(plain, wps->dev.mac_addr) ||
|
||||||
os_free(data);
|
wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
|
||||||
|
os_free(data.new_psk);
|
||||||
|
wpabuf_clear_free(plain);
|
||||||
return NULL;
|
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;
|
return plain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,13 +426,12 @@ struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id,
|
|||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (wps_build_version(data) ||
|
if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
|
||||||
wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
|
|
||||||
wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
|
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 "
|
wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
|
||||||
"token");
|
"token");
|
||||||
wpabuf_free(data);
|
wpabuf_clear_free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +453,7 @@ int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr)
|
|||||||
wpabuf_set(&msg, attr->cred[i], attr->cred_len[i]);
|
wpabuf_set(&msg, attr->cred[i], attr->cred_len[i]);
|
||||||
if (wps_parse_msg(&msg, &cattr) < 0 ||
|
if (wps_parse_msg(&msg, &cattr) < 0 ||
|
||||||
wps_process_cred(&cattr, &local_cred)) {
|
wps_process_cred(&cattr, &local_cred)) {
|
||||||
wpa_printf(MSG_ERROR, "WPS: Failed to parse OOB "
|
wpa_printf(MSG_ERROR, "WPS: Failed to parse OOB "
|
||||||
"credential");
|
"credential");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -438,13 +473,13 @@ int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN])
|
|||||||
|
|
||||||
/* <categ>-<OUI>-<subcateg> */
|
/* <categ>-<OUI>-<subcateg> */
|
||||||
WPA_PUT_BE16(dev_type, atoi(str));
|
WPA_PUT_BE16(dev_type, atoi(str));
|
||||||
pos = (char *)os_strchr(str, '-');
|
pos = os_strchr(str, '-');
|
||||||
if (pos == NULL)
|
if (pos == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
pos++;
|
pos++;
|
||||||
if (hexstr2bin(pos, &dev_type[2], 4))
|
if (hexstr2bin(pos, &dev_type[2], 4))
|
||||||
return -1;
|
return -1;
|
||||||
pos = (char *)os_strchr(pos, '-');
|
pos = os_strchr(pos, '-');
|
||||||
if (pos == NULL)
|
if (pos == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
pos++;
|
pos++;
|
||||||
@@ -460,10 +495,10 @@ char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
|
|||||||
{
|
{
|
||||||
int ret;
|
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), WPA_GET_BE32(&dev_type[2]),
|
||||||
WPA_GET_BE16(&dev_type[6]));
|
WPA_GET_BE16(&dev_type[6]));
|
||||||
if (ret < 0 || (unsigned int) ret >= buf_len)
|
if (os_snprintf_error(buf_len, ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
@@ -502,15 +537,16 @@ u16 wps_config_methods_str2bin(const char *str)
|
|||||||
{
|
{
|
||||||
u16 methods = 0;
|
u16 methods = 0;
|
||||||
|
|
||||||
if (str == NULL) {
|
if (str == NULL || str[0] == '\0') {
|
||||||
/* Default to enabling methods based on build configuration */
|
/* Default to enabling methods based on build configuration */
|
||||||
methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
|
methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
methods |= WPS_CONFIG_VIRT_DISPLAY;
|
methods |= WPS_CONFIG_VIRT_DISPLAY;
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#ifdef CONFIG_WPS_NFC
|
||||||
methods |= WPS_CONFIG_NFC_INTERFACE;
|
methods |= WPS_CONFIG_NFC_INTERFACE;
|
||||||
#endif /* CONFIG_WPS_NFC */
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
methods |= WPS_CONFIG_P2PS;
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
} else {
|
} else {
|
||||||
if (os_strstr(str, "ethernet"))
|
if (os_strstr(str, "ethernet"))
|
||||||
methods |= WPS_CONFIG_ETHERNET;
|
methods |= WPS_CONFIG_ETHERNET;
|
||||||
@@ -528,7 +564,6 @@ u16 wps_config_methods_str2bin(const char *str)
|
|||||||
methods |= WPS_CONFIG_PUSHBUTTON;
|
methods |= WPS_CONFIG_PUSHBUTTON;
|
||||||
if (os_strstr(str, "keypad"))
|
if (os_strstr(str, "keypad"))
|
||||||
methods |= WPS_CONFIG_KEYPAD;
|
methods |= WPS_CONFIG_KEYPAD;
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
if (os_strstr(str, "virtual_display"))
|
if (os_strstr(str, "virtual_display"))
|
||||||
methods |= WPS_CONFIG_VIRT_DISPLAY;
|
methods |= WPS_CONFIG_VIRT_DISPLAY;
|
||||||
if (os_strstr(str, "physical_display"))
|
if (os_strstr(str, "physical_display"))
|
||||||
@@ -537,7 +572,8 @@ u16 wps_config_methods_str2bin(const char *str)
|
|||||||
methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
|
methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
|
||||||
if (os_strstr(str, "physical_push_button"))
|
if (os_strstr(str, "physical_push_button"))
|
||||||
methods |= WPS_CONFIG_PHY_PUSHBUTTON;
|
methods |= WPS_CONFIG_PHY_PUSHBUTTON;
|
||||||
#endif /* CONFIG_WPS2 */
|
if (os_strstr(str, "p2ps"))
|
||||||
|
methods |= WPS_CONFIG_P2PS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return methods;
|
return methods;
|
||||||
@@ -548,7 +584,7 @@ struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
|
|||||||
{
|
{
|
||||||
struct wpabuf *msg;
|
struct wpabuf *msg;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
|
wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
|
||||||
|
|
||||||
msg = wpabuf_alloc(1000);
|
msg = wpabuf_alloc(1000);
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
@@ -558,7 +594,7 @@ struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
|
|||||||
wps_build_msg_type(msg, WPS_WSC_ACK) ||
|
wps_build_msg_type(msg, WPS_WSC_ACK) ||
|
||||||
wps_build_enrollee_nonce(wps, msg) ||
|
wps_build_enrollee_nonce(wps, msg) ||
|
||||||
wps_build_registrar_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);
|
wpabuf_free(msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -571,7 +607,7 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
|
|||||||
{
|
{
|
||||||
struct wpabuf *msg;
|
struct wpabuf *msg;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
|
wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
|
||||||
|
|
||||||
msg = wpabuf_alloc(1000);
|
msg = wpabuf_alloc(1000);
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
@@ -582,7 +618,7 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
|
|||||||
wps_build_enrollee_nonce(wps, msg) ||
|
wps_build_enrollee_nonce(wps, msg) ||
|
||||||
wps_build_registrar_nonce(wps, msg) ||
|
wps_build_registrar_nonce(wps, msg) ||
|
||||||
wps_build_config_error(msg, wps->config_error) ||
|
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);
|
wpabuf_free(msg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -592,12 +628,60 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#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 * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
|
||||||
struct wpabuf **privkey,
|
struct wpabuf **privkey,
|
||||||
struct wpabuf **dev_pw)
|
struct wpabuf **dev_pw)
|
||||||
{
|
{
|
||||||
struct wpabuf *priv = NULL, *pub = NULL, *pw, *ret;
|
struct wpabuf *pw;
|
||||||
void *dh_ctx;
|
|
||||||
u16 val;
|
u16 val;
|
||||||
|
|
||||||
pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dh_ctx = dh5_init(&priv, &pub);
|
if (wps_nfc_gen_dh(pubkey, privkey) < 0) {
|
||||||
if (dh_ctx == NULL) {
|
|
||||||
wpabuf_free(pw);
|
wpabuf_free(pw);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
dh5_free(dh_ctx);
|
|
||||||
|
|
||||||
*id = 0x10 + val % 0xfff0;
|
*id = 0x10 + val % 0xfff0;
|
||||||
wpabuf_free(*pubkey);
|
wpabuf_clear_free(*dev_pw);
|
||||||
*pubkey = pub;
|
|
||||||
wpabuf_free(*privkey);
|
|
||||||
*privkey = priv;
|
|
||||||
wpabuf_free(*dev_pw);
|
|
||||||
*dev_pw = pw;
|
*dev_pw = pw;
|
||||||
|
|
||||||
ret = wps_build_nfc_pw_token(*id, *pubkey, *dev_pw);
|
return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw);
|
||||||
if (ndef && ret) {
|
}
|
||||||
struct wpabuf *tmp;
|
|
||||||
tmp = ndef_build_wifi(ret);
|
|
||||||
wpabuf_free(ret);
|
struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx,
|
||||||
if (tmp == NULL)
|
struct wpabuf *nfc_dh_pubkey)
|
||||||
return NULL;
|
{
|
||||||
ret = tmp;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
@@ -12,16 +12,17 @@
|
|||||||
#ifdef CONFIG_WPS_TESTING
|
#ifdef CONFIG_WPS_TESTING
|
||||||
|
|
||||||
extern int wps_version_number;
|
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
|
#define WPS_VERSION wps_version_number
|
||||||
|
|
||||||
#else /* CONFIG_WPS_TESTING */
|
#else /* CONFIG_WPS_TESTING */
|
||||||
|
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
#define WPS_VERSION 0x20
|
#define WPS_VERSION 0x20
|
||||||
#else /* CONFIG_WPS2 */
|
|
||||||
#define WPS_VERSION 0x10
|
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
|
|
||||||
#endif /* CONFIG_WPS_TESTING */
|
#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_MIN_LEN 16
|
||||||
#define WPS_OOB_DEVICE_PASSWORD_LEN 32
|
#define WPS_OOB_DEVICE_PASSWORD_LEN 32
|
||||||
#define WPS_OOB_PUBKEY_HASH_LEN 20
|
#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 */
|
/* Attribute Types */
|
||||||
enum wps_attribute {
|
enum wps_attribute {
|
||||||
@@ -145,7 +151,9 @@ enum {
|
|||||||
WFA_ELEM_AUTHORIZEDMACS = 0x01,
|
WFA_ELEM_AUTHORIZEDMACS = 0x01,
|
||||||
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
|
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
|
||||||
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
|
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 */
|
/* Device Password ID */
|
||||||
@@ -155,13 +163,9 @@ enum wps_dev_password_id {
|
|||||||
DEV_PW_MACHINE_SPECIFIED = 0x0002,
|
DEV_PW_MACHINE_SPECIFIED = 0x0002,
|
||||||
DEV_PW_REKEY = 0x0003,
|
DEV_PW_REKEY = 0x0003,
|
||||||
DEV_PW_PUSHBUTTON = 0x0004,
|
DEV_PW_PUSHBUTTON = 0x0004,
|
||||||
DEV_PW_REGISTRAR_SPECIFIED = 0x0005
|
DEV_PW_REGISTRAR_SPECIFIED = 0x0005,
|
||||||
};
|
DEV_PW_NFC_CONNECTION_HANDOVER = 0x0007,
|
||||||
|
DEV_PW_P2PS_DEFAULT = 0x0008
|
||||||
/* WPS message flag */
|
|
||||||
enum wps_msg_flag {
|
|
||||||
WPS_MSG_FLAG_MORE = 0x01,
|
|
||||||
WPS_MSG_FLAG_LEN = 0x02
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Message Type */
|
/* Message Type */
|
||||||
@@ -184,18 +188,18 @@ enum wps_msg_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Authentication Type Flags */
|
/* Authentication Type Flags */
|
||||||
#define WPS_WIFI_AUTH_OPEN 0x0001
|
#define WPS_AUTH_OPEN 0x0001
|
||||||
#define WPS_AUTH_WPAPSK 0x0002
|
#define WPS_AUTH_WPAPSK 0x0002
|
||||||
#define WPS_AUTH_SHARED 0x0004
|
#define WPS_AUTH_SHARED 0x0004 /* deprecated */
|
||||||
#define WPS_AUTH_WPA 0x0008
|
#define WPS_AUTH_WPA 0x0008
|
||||||
#define WPS_AUTH_WPA2 0x0010
|
#define WPS_AUTH_WPA2 0x0010
|
||||||
#define WPS_AUTH_WPA2PSK 0x0020
|
#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)
|
WPS_AUTH_WPA | WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)
|
||||||
|
|
||||||
/* Encryption Type Flags */
|
/* Encryption Type Flags */
|
||||||
#define WPS_ENCR_NONE 0x0001
|
#define WPS_ENCR_NONE 0x0001
|
||||||
#define WPS_ENCR_WEP 0x0002
|
#define WPS_ENCR_WEP 0x0002 /* deprecated */
|
||||||
#define WPS_ENCR_TKIP 0x0004
|
#define WPS_ENCR_TKIP 0x0004
|
||||||
#define WPS_ENCR_AES 0x0008
|
#define WPS_ENCR_AES 0x0008
|
||||||
#define WPS_ENCR_TYPES (WPS_ENCR_NONE | WPS_ENCR_WEP | WPS_ENCR_TKIP | \
|
#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_SETUP_LOCKED = 15,
|
||||||
WPS_CFG_MSG_TIMEOUT = 16,
|
WPS_CFG_MSG_TIMEOUT = 16,
|
||||||
WPS_CFG_REG_SESS_TIMEOUT = 17,
|
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 */
|
/* Vendor specific Error Indication for WPS event messages */
|
||||||
@@ -229,12 +235,14 @@ enum wps_error_indication {
|
|||||||
WPS_EI_NO_ERROR,
|
WPS_EI_NO_ERROR,
|
||||||
WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
|
WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
|
||||||
WPS_EI_SECURITY_WEP_PROHIBITED,
|
WPS_EI_SECURITY_WEP_PROHIBITED,
|
||||||
|
WPS_EI_AUTH_FAILURE,
|
||||||
NUM_WPS_EI_VALUES
|
NUM_WPS_EI_VALUES
|
||||||
};
|
};
|
||||||
|
|
||||||
/* RF Bands */
|
/* RF Bands */
|
||||||
#define WPS_RF_24GHZ 0x01
|
#define WPS_RF_24GHZ 0x01
|
||||||
#define WPS_RF_50GHZ 0x02
|
#define WPS_RF_50GHZ 0x02
|
||||||
|
#define WPS_RF_60GHZ 0x04
|
||||||
|
|
||||||
/* Config Methods */
|
/* Config Methods */
|
||||||
#define WPS_CONFIG_USBA 0x0001
|
#define WPS_CONFIG_USBA 0x0001
|
||||||
@@ -246,12 +254,11 @@ enum wps_error_indication {
|
|||||||
#define WPS_CONFIG_NFC_INTERFACE 0x0040
|
#define WPS_CONFIG_NFC_INTERFACE 0x0040
|
||||||
#define WPS_CONFIG_PUSHBUTTON 0x0080
|
#define WPS_CONFIG_PUSHBUTTON 0x0080
|
||||||
#define WPS_CONFIG_KEYPAD 0x0100
|
#define WPS_CONFIG_KEYPAD 0x0100
|
||||||
#ifdef CONFIG_WPS2
|
|
||||||
#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
|
#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
|
||||||
#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
|
#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
|
||||||
|
#define WPS_CONFIG_P2PS 0x1000
|
||||||
#define WPS_CONFIG_VIRT_DISPLAY 0x2008
|
#define WPS_CONFIG_VIRT_DISPLAY 0x2008
|
||||||
#define WPS_CONFIG_PHY_DISPLAY 0x4008
|
#define WPS_CONFIG_PHY_DISPLAY 0x4008
|
||||||
#endif /* CONFIG_WPS2 */
|
|
||||||
|
|
||||||
/* Connection Type Flags */
|
/* Connection Type Flags */
|
||||||
#define WPS_CONN_ESS 0x01
|
#define WPS_CONN_ESS 0x01
|
||||||
@@ -285,7 +292,8 @@ enum wps_dev_categ {
|
|||||||
WPS_DEV_DISPLAY = 7,
|
WPS_DEV_DISPLAY = 7,
|
||||||
WPS_DEV_MULTIMEDIA = 8,
|
WPS_DEV_MULTIMEDIA = 8,
|
||||||
WPS_DEV_GAMING = 9,
|
WPS_DEV_GAMING = 9,
|
||||||
WPS_DEV_PHONE = 10
|
WPS_DEV_PHONE = 10,
|
||||||
|
WPS_DEV_AUDIO = 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wps_dev_subcateg {
|
enum wps_dev_subcateg {
|
||||||
@@ -334,8 +342,4 @@ enum wps_response_type {
|
|||||||
|
|
||||||
#define WPS_MAX_AUTHORIZED_MACS 5
|
#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 */
|
#endif /* WPS_DEFS_H */
|
||||||
|
@@ -5,11 +5,13 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
#include "utils/includes.h"
|
|
||||||
#include "utils/common.h"
|
|
||||||
|
|
||||||
#include "wps/wps_i.h"
|
#include "includes.h"
|
||||||
#include "wps/wps_dev_attr.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)
|
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,
|
int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg)
|
||||||
struct wpabuf *msg)
|
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
wpa_printf(MSG_DEBUG, "WPS: * Serial Number");
|
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);
|
return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
|
||||||
wpabuf_put_be16(msg, ATTR_RF_BANDS);
|
|
||||||
wpabuf_put_be16(msg, 1);
|
|
||||||
wpabuf_put_u8(msg, dev->rf_bands);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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,
|
static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
|
||||||
size_t str_len)
|
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);
|
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
|
||||||
|
|
||||||
os_free(dev->manufacturer);
|
os_free(dev->manufacturer);
|
||||||
dev->manufacturer = (char *)os_malloc(str_len + 1);
|
dev->manufacturer = dup_binstr(str, str_len);
|
||||||
if (dev->manufacturer == NULL)
|
if (dev->manufacturer == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(dev->manufacturer, str, str_len);
|
|
||||||
dev->manufacturer[str_len] = '\0';
|
|
||||||
|
|
||||||
return 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);
|
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
|
||||||
|
|
||||||
os_free(dev->model_name);
|
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)
|
if (dev->model_name == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(dev->model_name, str, str_len);
|
|
||||||
dev->model_name[str_len] = '\0';
|
|
||||||
|
|
||||||
return 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);
|
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
|
||||||
|
|
||||||
os_free(dev->model_number);
|
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)
|
if (dev->model_number == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(dev->model_number, str, str_len);
|
|
||||||
dev->model_number[str_len] = '\0';
|
|
||||||
|
|
||||||
return 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);
|
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
|
||||||
|
|
||||||
os_free(dev->serial_number);
|
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)
|
if (dev->serial_number == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(dev->serial_number, str, str_len);
|
|
||||||
dev->serial_number[str_len] = '\0';
|
|
||||||
|
|
||||||
return 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);
|
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
|
||||||
|
|
||||||
os_free(dev->device_name);
|
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)
|
if (dev->device_name == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(dev->device_name, str, str_len);
|
|
||||||
dev->device_name[str_len] = '\0';
|
|
||||||
|
|
||||||
return 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,
|
static int wps_process_primary_dev_type(struct wps_device_data *dev,
|
||||||
const u8 *dev_type)
|
const u8 *dev_type)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
char devtype[WPS_DEV_TYPE_BUFSIZE];
|
||||||
|
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||||
|
|
||||||
if (dev_type == NULL) {
|
if (dev_type == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
|
wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
|
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;
|
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)
|
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
|
||||||
{
|
{
|
||||||
if (bands == NULL) {
|
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)
|
void wps_device_data_free(struct wps_device_data *dev)
|
||||||
{
|
{
|
||||||
os_free(dev->device_name);
|
os_free(dev->device_name);
|
||||||
@@ -440,4 +441,6 @@ void wps_device_data_free(struct wps_device_data *dev)
|
|||||||
dev->model_number = NULL;
|
dev->model_number = NULL;
|
||||||
os_free(dev->serial_number);
|
os_free(dev->serial_number);
|
||||||
dev->serial_number = NULL;
|
dev->serial_number = NULL;
|
||||||
|
wpabuf_free(dev->application_ext);
|
||||||
|
dev->application_ext = NULL;
|
||||||
}
|
}
|
||||||
|
@@ -14,11 +14,13 @@ struct wps_parse_attr;
|
|||||||
int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg);
|
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_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_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_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_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_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_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,
|
int wps_build_primary_dev_type(struct wps_device_data *dev,
|
||||||
struct wpabuf *msg);
|
struct wpabuf *msg);
|
||||||
int wps_build_secondary_dev_type(struct wps_device_data *dev,
|
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,
|
int wps_process_device_attrs(struct wps_device_data *dev,
|
||||||
struct wps_parse_attr *attr);
|
struct wps_parse_attr *attr);
|
||||||
int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
|
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);
|
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);
|
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_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,
|
int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
|
||||||
unsigned int num_req_dev_types,
|
unsigned int num_req_dev_types,
|
||||||
const u8 *req_dev_types);
|
const u8 *req_dev_types);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
#include "wps.h"
|
#include "wps.h"
|
||||||
#include "wps_attr_parse.h"
|
#include "wps_attr_parse.h"
|
||||||
#include "esp_wps.h"
|
|
||||||
#include "esp_wifi_crypto_types.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#ifdef CONFIG_WPS_NFC
|
||||||
struct wps_nfc_pw_token;
|
struct wps_nfc_pw_token;
|
||||||
@@ -74,6 +72,12 @@ struct wps_data {
|
|||||||
size_t dev_password_len;
|
size_t dev_password_len;
|
||||||
u16 dev_pw_id;
|
u16 dev_pw_id;
|
||||||
int pbc;
|
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
|
* 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
|
u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
|
||||||
* 00:00:00:00:00:00 if not a P2p client */
|
* 00:00:00:00:00:00 if not a P2p client */
|
||||||
int pbc_in_m1;
|
int pbc_in_m1;
|
||||||
#ifdef CONFIG_WPS_NFC
|
|
||||||
struct wps_nfc_pw_token *nfc_pw_token;
|
struct wps_nfc_pw_token *nfc_pw_token;
|
||||||
#endif
|
|
||||||
|
int multi_ap_backhaul_sta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* wps_common.c */
|
/* wps_common.c */
|
||||||
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
|
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
|
||||||
const char *label, u8 *res, size_t res_len);
|
const char *label, u8 *res, size_t res_len);
|
||||||
int wps_derive_keys(struct wps_data *wps);
|
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);
|
size_t dev_passwd_len);
|
||||||
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
|
||||||
size_t encr_len);
|
size_t encr_len);
|
||||||
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
|
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);
|
||||||
void wps_success_event(struct wps_context *wps);
|
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);
|
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_overlap_event(struct wps_context *wps);
|
||||||
void wps_pbc_timeout_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_ack(struct wps_data *wps);
|
||||||
struct wpabuf * wps_build_wsc_nack(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 */
|
/* 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_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_resp_type(struct wpabuf *msg, enum wps_response_type type);
|
||||||
int wps_build_config_methods(struct wpabuf *msg, u16 methods);
|
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);
|
struct wpabuf *plain);
|
||||||
int wps_build_version(struct wpabuf *msg);
|
int wps_build_version(struct wpabuf *msg);
|
||||||
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
|
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_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_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
|
||||||
int wps_build_registrar_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,
|
const struct wpabuf *pubkey, const u8 *dev_pw,
|
||||||
size_t dev_pw_len);
|
size_t dev_pw_len);
|
||||||
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data);
|
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 */
|
/* wps_attr_process.c */
|
||||||
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
|
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_build_cred(struct wps_data *wps, struct wpabuf *msg);
|
||||||
int wps_device_store(struct wps_registrar *reg,
|
int wps_device_store(struct wps_registrar *reg,
|
||||||
struct wps_device_data *dev, const u8 *uuid);
|
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);
|
const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count);
|
||||||
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
|
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
|
||||||
const u8 *addr, const u8 *uuid_e);
|
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,
|
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
|
||||||
struct wps_nfc_pw_token *token);
|
struct wps_nfc_pw_token *token);
|
||||||
#endif
|
#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 */
|
#endif /* WPS_I_H */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,15 +5,14 @@
|
|||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "wps/wps_i.h"
|
#include "wps_i.h"
|
||||||
#include "wps/wps.h"
|
#include "wps.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_STRICT
|
|
||||||
|
|
||||||
#ifndef WPS_STRICT_ALL
|
#ifndef WPS_STRICT_ALL
|
||||||
#define WPS_STRICT_WPS2
|
#define WPS_STRICT_WPS2
|
||||||
#endif /* WPS_STRICT_ALL */
|
#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)
|
static int valid_config_methods(u16 val, int wps2)
|
||||||
{
|
{
|
||||||
if (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)) {
|
if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
|
||||||
wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
|
wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
|
||||||
"without Physical/Virtual Display flag");
|
"without Physical/Virtual Display flag");
|
||||||
return 0;
|
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)) {
|
if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
|
||||||
wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
|
wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
|
||||||
"without Physical/Virtual 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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
|
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)) {
|
*rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
|
||||||
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
|
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
|
||||||
"attribute value 0x%x", *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;
|
return 0;
|
||||||
}
|
}
|
||||||
val = WPA_GET_BE16(config_error);
|
val = WPA_GET_BE16(config_error);
|
||||||
if (val > 18) {
|
if (val > 20) {
|
||||||
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
|
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
|
||||||
"attribute value 0x%04x", val);
|
"attribute value 0x%04x", val);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -279,7 +292,7 @@ static int wps_validate_dev_password_id(const u8 *dev_password_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
val = WPA_GET_BE16(dev_password_id);
|
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 "
|
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
|
||||||
"attribute value 0x%04x", val);
|
"attribute value 0x%04x", val);
|
||||||
return -1;
|
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)
|
int mandatory)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -2363,4 +2376,3 @@ _out:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@@ -1657,13 +1657,10 @@ components/wifi_provisioning/src/wifi_config.c
|
|||||||
components/wifi_provisioning/src/wifi_provisioning_priv.h
|
components/wifi_provisioning/src/wifi_provisioning_priv.h
|
||||||
components/wifi_provisioning/src/wifi_scan.c
|
components/wifi_provisioning/src/wifi_scan.c
|
||||||
components/wpa_supplicant/esp_supplicant/include/esp_rrm.h
|
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_scan_i.h
|
||||||
components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c
|
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_wpa3_i.h
|
||||||
components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.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/wpa_debug.h
|
||||||
components/wpa_supplicant/include/utils/wpabuf.h
|
components/wpa_supplicant/include/utils/wpabuf.h
|
||||||
components/wpa_supplicant/port/include/byteswap.h
|
components/wpa_supplicant/port/include/byteswap.h
|
||||||
|
Reference in New Issue
Block a user