mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(esp_wifi): Add support for multiconfig support for DPP
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -18,6 +18,14 @@ extern "C" {
|
||||
|
||||
#define ESP_DPP_MAX_CHAN_COUNT 5
|
||||
|
||||
#ifndef ESP_DPP_MAX_CONFIG_COUNT
|
||||
#ifdef CONFIG_ESP_WIFI_DPP_MAX_CONF_OBJ
|
||||
#define ESP_DPP_MAX_CONFIG_COUNT CONFIG_ESP_WIFI_DPP_MAX_CONF_OBJ
|
||||
#else
|
||||
#define ESP_DPP_MAX_CONFIG_COUNT 3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
|
||||
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
|
||||
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
|
||||
@@ -25,6 +33,22 @@ extern "C" {
|
||||
#define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */
|
||||
#define ESP_ERR_DPP_CONF_TIMEOUT (ESP_ERR_WIFI_BASE + 156) /*!< DPP Configuration was not received in time */
|
||||
|
||||
/**
|
||||
* @brief AKM values for one DPP configuration row (which credentials apply and how to connect).
|
||||
*
|
||||
* Use this with fields in esp_dpp_config_data_t: legacy modes use password,
|
||||
* DPP modes use connector and network access key via esp_supp_dpp_set_config().
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_DPP_AKM_UNKNOWN = 0, /**< Not set or unrecognized */
|
||||
ESP_DPP_AKM_DPP = 1, /**< DPP-only: connector and network access key */
|
||||
ESP_DPP_AKM_PSK = 2, /**< WPA2-PSK: passphrase in password */
|
||||
ESP_DPP_AKM_SAE = 3, /**< WPA3-SAE: passphrase in password */
|
||||
ESP_DPP_AKM_PSK_SAE = 4, /**< WPA2/WPA3 transition: passphrase in password */
|
||||
ESP_DPP_AKM_SAE_DPP = 5, /**< SAE plus DPP: passphrase and DPP credentials */
|
||||
ESP_DPP_AKM_PSK_SAE_DPP = 6, /**< WPA2/WPA3 plus DPP: passphrase and DPP credentials */
|
||||
} esp_dpp_akm_t;
|
||||
|
||||
/** @brief Types of Bootstrap Methods for DPP. */
|
||||
typedef enum dpp_bootstrap_type {
|
||||
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
|
||||
@@ -37,10 +61,9 @@ typedef enum dpp_bootstrap_type {
|
||||
*
|
||||
* Starts DPP Supplicant and initializes related Data Structures.
|
||||
*
|
||||
* @return
|
||||
* return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_DPP_FAILURE: Generic failure or already initialized
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed
|
||||
* - ESP_FAIL: Failure
|
||||
*/
|
||||
esp_err_t esp_supp_dpp_init(void);
|
||||
|
||||
@@ -51,7 +74,6 @@ esp_err_t esp_supp_dpp_init(void);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_DPP_FAILURE: Failed to schedule deinitialization
|
||||
*/
|
||||
esp_err_t esp_supp_dpp_deinit(void);
|
||||
|
||||
@@ -61,20 +83,16 @@ esp_err_t esp_supp_dpp_deinit(void);
|
||||
* Generates Out Of Band Bootstrap information as an Enrollee which can be
|
||||
* used by a DPP Configurator to provision the Enrollee.
|
||||
*
|
||||
* @param chan_list List of channels device will be available on for listening
|
||||
* @param chan_list List of channels device will be available on for listening (must not be NULL)
|
||||
* @param type Bootstrap method type, only QR Code method is supported for now.
|
||||
* @param key (Optional) 32 byte hex-encoded Private Key for generating a Bootstrapping Public Key
|
||||
* @param key (Optional) 32 byte Raw Private Key for generating a Bootstrapping Public Key
|
||||
* @param info (Optional) Ancillary Device Information like Serial Number
|
||||
*
|
||||
* @note Since this API is asynchronous, internal failures during generation (e.g. OOM or crypto errors)
|
||||
* will be reported via the WIFI_EVENT_DPP_FAILED event.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success (generation started asynchronously)
|
||||
* - ESP_ERR_INVALID_STATE: DPP not initialized or shutting down
|
||||
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid or too long
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed
|
||||
* - ESP_ERR_NOT_SUPPORTED: Requested bootstrap type not supported
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: chan_list is NULL
|
||||
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
|
||||
* - ESP_FAIL: Failure
|
||||
*/
|
||||
esp_err_t
|
||||
esp_supp_dpp_bootstrap_gen(const char *chan_list, esp_supp_dpp_bootstrap_t type,
|
||||
@@ -87,8 +105,9 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, esp_supp_dpp_bootstrap_t type,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: ROC attempted before WiFi is started, or DPP not initialized/bootstrapped
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed while scheduling listen operation
|
||||
* - ESP_FAIL: Generic Failure
|
||||
* - ESP_ERR_INVALID_STATE: ROC attempted before WiFi is started
|
||||
* - ESP_ERR_NO_MEM: Memory allocation failed while posting ROC request
|
||||
*/
|
||||
esp_err_t esp_supp_dpp_start_listen(void);
|
||||
|
||||
@@ -99,10 +118,34 @@ esp_err_t esp_supp_dpp_start_listen(void);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_FAIL: Failure to schedule listen stop
|
||||
* - ESP_FAIL: Failure
|
||||
*/
|
||||
esp_err_t esp_supp_dpp_stop_listen(void);
|
||||
|
||||
/**
|
||||
* @brief Install or clear DPP AKM connector material in the supplicant.
|
||||
*
|
||||
* This function copies the given DPP AKM row (connector and related keys) into the
|
||||
* supplicant; only one such row is retained, and a new row replaces the previous one.
|
||||
* Pass NULL to clear the stored row. (If the first configuration object in the
|
||||
* Configuration Response uses a DPP AKM with a connector, the stack may load it into the
|
||||
* same store before the event is delivered; NULL clears that selection too.)
|
||||
*
|
||||
* Connection retry/fallback policy is application-owned. Typical sequence per selected
|
||||
* row is: pick one row from WIFI_EVENT_DPP_CFG_RECVD, call esp_wifi_set_config(),
|
||||
* call esp_supp_dpp_set_config() using connector values received from
|
||||
* WIFI_EVENT_DPP_CFG_RECVD, call esp_wifi_connect().
|
||||
*
|
||||
* @param config Pointer to one DPP AKM row from WIFI_EVENT_DPP_CFG_RECVD, or NULL to clear.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: @a config is not a DPP AKM row, or key lengths are invalid
|
||||
* - ESP_ERR_INVALID_STATE: DPP supplicant not initialized
|
||||
* - ESP_ERR_NO_MEM: Allocation failed while storing the row
|
||||
*/
|
||||
esp_err_t esp_supp_dpp_set_config(const esp_dpp_config_data_t *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1683,8 +1683,13 @@ struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group
|
||||
key_bits = bits;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
if (ecc_family == PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
|
||||
} else {
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
}
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_family));
|
||||
psa_set_key_bits(&key_attributes, key_bits);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "esp_scan_i.h"
|
||||
#include "esp_common_i.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "esp_dpp.h"
|
||||
#include "esp_dpp_i.h"
|
||||
#include "esp_rrm.h"
|
||||
#include "esp_wnm.h"
|
||||
#include "rsn_supp/wpa_i.h"
|
||||
|
||||
@@ -28,9 +28,6 @@ bool mbo_bss_profile_match(u8 *bssid);
|
||||
#endif /* defined(CONFIG_RRM) || defined(CONFIG_WNM) */
|
||||
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb);
|
||||
void esp_supplicant_common_deinit(void);
|
||||
#ifdef CONFIG_DPP
|
||||
esp_err_t esp_supp_dpp_common_init(void);
|
||||
#endif
|
||||
void esp_supplicant_unset_all_appie(void);
|
||||
void esp_set_scan_ie(void);
|
||||
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool add_mdie);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,10 +12,10 @@
|
||||
#include "utils/common.h"
|
||||
#include "common/dpp.h"
|
||||
#include "esp_dpp.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
|
||||
#define ESP_DPP_AUTH_TIMEOUT_SECS 2
|
||||
#define ESP_GAS_TIMEOUT_SECS 2
|
||||
#define ESP_DPP_GAS_REASSEMBLY_MAX_LEN 4096
|
||||
#define ESP_DPP_PMK_CACHE_DEFAULT_TIMEOUT (86400 * 7) /*!< 7 days */
|
||||
|
||||
#define BOOTSTRAP_ROC_WAIT_TIME 500
|
||||
@@ -34,24 +34,32 @@ enum dpp_tx_frame_type {
|
||||
DPP_TX_AUTHENTICATION_CONF,
|
||||
DPP_TX_PEER_DISCOVERY_REQ,
|
||||
DPP_TX_GAS_CONFIG_REQ,
|
||||
DPP_TX_GAS_COMEBACK,
|
||||
};
|
||||
|
||||
struct esp_dpp_context_t {
|
||||
struct dpp_bootstrap_params_t bootstrap_params;
|
||||
struct dpp_authentication *dpp_auth;
|
||||
int gas_dialog_token;
|
||||
struct dpp_global *dpp_global;
|
||||
wifi_config_t wifi_cfg;
|
||||
int id;
|
||||
bool dpp_deinit_pending; /* True while deinit is queued so init is rejected until it finishes */
|
||||
bool bootstrap_done;
|
||||
bool dpp_listen_ongoing;
|
||||
struct dpp_config_store *dpp_config_store;
|
||||
/* Fragmented GAS Configuration Response */
|
||||
struct wpabuf *gas_resp_buf; /* Reassembled query response data */
|
||||
uint8_t gas_frag_id; /* Expected next fragment id */
|
||||
bool gas_wait_comeback; /* Waiting for GAS Comeback Response */
|
||||
/* Retry counter for GAS query and peer discovery TX */
|
||||
unsigned int gas_query_tries;
|
||||
/* Last off-channel TX for status matching */
|
||||
struct {
|
||||
uint8_t op_id;
|
||||
enum dpp_tx_frame_type type;
|
||||
} pending_tx_op;
|
||||
bool pending_tx_op_in_progress;
|
||||
unsigned int gas_query_tries;
|
||||
unsigned int listen_chan_idx;
|
||||
int id;
|
||||
bool dpp_deinit_pending;
|
||||
bool bootstrap_done;
|
||||
bool dpp_listen_ongoing;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
@@ -59,12 +67,17 @@ int dpp_test_gen_invalid_key(struct wpabuf *msg, const struct dpp_curve_params *
|
||||
char * dpp_corrupt_connector_signature(const char *connector);
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_DPP_SUPPORT
|
||||
#ifdef CONFIG_DPP
|
||||
bool is_dpp_enabled(void);
|
||||
esp_err_t esp_supp_dpp_common_init(void);
|
||||
#else
|
||||
static inline bool is_dpp_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline esp_err_t esp_supp_dpp_common_init(void)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
#endif /* ESP_DPP_I_H */
|
||||
|
||||
@@ -551,20 +551,12 @@ int esp_supplicant_init(void)
|
||||
esp_wifi_register_owe_cb(wpa_cb);
|
||||
#endif /* CONFIG_OWE_STA */
|
||||
|
||||
if (eloop_init() != 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to initialize eloop");
|
||||
os_free(wpa_cb);
|
||||
wpa_cb = NULL;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
eloop_init();
|
||||
ret = esp_supplicant_common_init(wpa_cb);
|
||||
|
||||
if (ret != 0) {
|
||||
/*
|
||||
* Note: We don't need to explicitly call eloop_destroy() here because
|
||||
* returning an error causes the caller (esp_wifi_init) to trigger the
|
||||
* deinit path, which invokes esp_supplicant_deinit() and frees the eloop.
|
||||
/* esp_wifi_init() propagates this error to wifi_deinit_internal() which calls
|
||||
* esp_supplicant_deinit(); that path runs eloop_destroy() for eloop cleanup.
|
||||
*/
|
||||
os_free(wpa_cb);
|
||||
wpa_cb = NULL;
|
||||
|
||||
@@ -98,17 +98,9 @@ struct wpabuf * gas_build_initial_req(u8 dialog_token, size_t size)
|
||||
size);
|
||||
}
|
||||
|
||||
void dpp_debug_print_point(const char *title, struct crypto_ec *e,
|
||||
const struct crypto_ec_point *point)
|
||||
struct wpabuf * gas_build_comeback_req(u8 dialog_token)
|
||||
{
|
||||
u8 x[64], y[64];
|
||||
|
||||
if (crypto_ec_point_to_bin(e, point, x, y) < 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to get coordinates");
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x, y);
|
||||
return gas_build_req(WLAN_PA_GAS_COMEBACK_REQ, dialog_token, 0);
|
||||
}
|
||||
|
||||
static void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
|
||||
@@ -495,7 +487,7 @@ static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth,
|
||||
|
||||
/* Build DPP Authentication Request frame attributes */
|
||||
attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + (pi ? wpabuf_len(pi) : 0) +
|
||||
4 + sizeof(wrapped_data);
|
||||
4 + sizeof(wrapped_data) + 5;
|
||||
if (neg_freq > 0)
|
||||
attr_len += 4 + 2;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
@@ -532,6 +524,11 @@ static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth,
|
||||
wpabuf_put_u8(msg, channel);
|
||||
}
|
||||
|
||||
/* Protocol version: advertise v2 */
|
||||
wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
|
||||
wpabuf_put_le16(msg, 1);
|
||||
wpabuf_put_u8(msg, 2);
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_REQ) {
|
||||
wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
|
||||
@@ -658,6 +655,9 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
|
||||
/* Build DPP Authentication Response frame attributes */
|
||||
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
||||
4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
|
||||
/* Protocol Version attribute is added below when peer_version >= 2 */
|
||||
if (auth->peer_version >= 2)
|
||||
attr_len += 5;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
|
||||
attr_len += 5;
|
||||
@@ -685,6 +685,13 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
|
||||
wpabuf_put_buf(msg, pr);
|
||||
}
|
||||
|
||||
/* Protocol version for v2 peer */
|
||||
if (auth->peer_version >= 2) {
|
||||
wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
|
||||
wpabuf_put_le16(msg, 1);
|
||||
wpabuf_put_u8(msg, 2);
|
||||
}
|
||||
|
||||
attr_end = wpabuf_put(msg, 0);
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
@@ -803,30 +810,97 @@ skip_wrapped_data:
|
||||
return msg;
|
||||
}
|
||||
|
||||
struct wpabuf * dpp_build_peer_disc_req(struct dpp_authentication *auth, struct dpp_config_obj *conf)
|
||||
struct json_token * dpp_parse_own_connector(const char *own_connector);
|
||||
|
||||
static u8 dpp_get_connector_version(const char *connector)
|
||||
{
|
||||
struct json_token *root, *token;
|
||||
u8 version = 1;
|
||||
|
||||
root = dpp_parse_own_connector(connector);
|
||||
if (!root)
|
||||
return 1;
|
||||
|
||||
token = json_get_member(root, "version");
|
||||
if (!token)
|
||||
token = json_get_member(root, "v");
|
||||
|
||||
if (token && token->type == JSON_NUMBER)
|
||||
version = token->number;
|
||||
|
||||
json_free(root);
|
||||
return version;
|
||||
}
|
||||
|
||||
void dpp_clear_confs(struct dpp_conf *conf)
|
||||
{
|
||||
if (!conf)
|
||||
return;
|
||||
if (conf->connector)
|
||||
bin_clear_free(conf->connector, os_strlen(conf->connector));
|
||||
wpabuf_clear_free(conf->c_sign_key);
|
||||
wpabuf_clear_free(conf->net_access_key);
|
||||
bin_clear_free(conf, sizeof(*conf));
|
||||
}
|
||||
|
||||
void dpp_config_store_deinit(struct dpp_config_store *dc)
|
||||
{
|
||||
if (!dc)
|
||||
return;
|
||||
dpp_clear_confs(dc->conf);
|
||||
dc->conf = NULL;
|
||||
bin_clear_free(dc, sizeof(*dc));
|
||||
}
|
||||
|
||||
struct dpp_config_store * dpp_config_store_init(void)
|
||||
{
|
||||
struct dpp_config_store *dc;
|
||||
|
||||
dc = os_zalloc(sizeof(*dc));
|
||||
if (!dc)
|
||||
return NULL;
|
||||
return dc;
|
||||
}
|
||||
|
||||
struct wpabuf * dpp_build_peer_disc_req(struct dpp_config_store *dc, struct dpp_conf *conf)
|
||||
{
|
||||
struct wpabuf *msg;
|
||||
size_t len;
|
||||
struct os_time now;
|
||||
int version;
|
||||
|
||||
if (!conf || !conf->connector || !auth || !auth->net_access_key || !conf->c_sign_key) {
|
||||
wpa_printf(MSG_ERROR, "missing %s", !conf->connector ? "Connector" : !auth->net_access_key ? "netAccessKey" : "C-sign-key");
|
||||
if (!dc) {
|
||||
wpa_printf(MSG_ERROR, "missing DPP config store");
|
||||
return NULL;
|
||||
}
|
||||
if (!conf) {
|
||||
wpa_printf(MSG_ERROR, "missing DPP config");
|
||||
return NULL;
|
||||
}
|
||||
if (!conf->connector || !conf->net_access_key || !conf->c_sign_key) {
|
||||
wpa_printf(MSG_ERROR, "missing %s",
|
||||
!conf->connector ? "Connector" :
|
||||
!conf->net_access_key ? "netAccessKey" : "C-sign-key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_get_time(&now);
|
||||
|
||||
if (auth->net_access_key_expiry &&
|
||||
(os_time_t) auth->net_access_key_expiry < now.sec) {
|
||||
if (conf->net_access_key_expiry &&
|
||||
(os_time_t) conf->net_access_key_expiry < now.sec) {
|
||||
wpa_printf(MSG_ERROR, "netAccessKey expired");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
version = dpp_get_connector_version(conf->connector);
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Starting network introduction protocol to derive PMKSA for "
|
||||
MACSTR, MAC2STR(auth->peer_mac_addr));
|
||||
MACSTR, MAC2STR(dc->peer_mac_addr));
|
||||
|
||||
len = TRANSACTION_ID_ATTR_SET_LEN + CONNECTOR_ATTR_SET_LEN + os_strlen(conf->connector);
|
||||
if (version >= 2)
|
||||
len += 5;
|
||||
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ, len);
|
||||
if (!msg) {
|
||||
return NULL;
|
||||
@@ -852,6 +926,15 @@ struct wpabuf * dpp_build_peer_disc_req(struct dpp_authentication *auth, struct
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
skip_trans_id:
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
if (version >= 2) {
|
||||
wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
|
||||
wpabuf_put_le16(msg, 1);
|
||||
wpabuf_put_u8(msg, version);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ) {
|
||||
wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
|
||||
goto skip_connector;
|
||||
@@ -1736,11 +1819,13 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||
const u8 *i_nonce;
|
||||
const u8 *i_capab;
|
||||
const u8 *i_bootstrap;
|
||||
const u8 *version;
|
||||
u16 wrapped_data_len;
|
||||
u16 i_proto_len;
|
||||
u16 i_nonce_len;
|
||||
u16 i_capab_len;
|
||||
u16 i_bootstrap_len;
|
||||
u16 version_len;
|
||||
struct dpp_authentication *auth = NULL;
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
u64 start_us = dpp_time_us();
|
||||
@@ -1777,6 +1862,13 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||
auth->curr_chan = curr_chan;
|
||||
|
||||
auth->peer_version = 1; /* default to the first version */
|
||||
version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
|
||||
&version_len);
|
||||
if (version && version_len >= 1 && version[0] >= 2) {
|
||||
auth->peer_version = version[0];
|
||||
wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
|
||||
auth->peer_version);
|
||||
}
|
||||
|
||||
#if 0
|
||||
channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL,
|
||||
@@ -2293,17 +2385,17 @@ struct wpabuf *
|
||||
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len)
|
||||
{
|
||||
struct crypto_ec_key *pr;
|
||||
struct crypto_ec_key *pr = NULL;
|
||||
size_t secret_len = 0;
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
u8 *unwrapped = NULL, *unwrapped2 = NULL;
|
||||
size_t unwrapped_len = 0, unwrapped2_len = 0;
|
||||
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
|
||||
*r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth;
|
||||
*r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth, *version;
|
||||
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
|
||||
r_proto_len, r_nonce_len, i_nonce_len, r_capab_len,
|
||||
wrapped2_len, r_auth_len;
|
||||
wrapped2_len, r_auth_len, version_len;
|
||||
u8 r_auth2[DPP_MAX_HASH_LEN];
|
||||
u8 role;
|
||||
|
||||
@@ -2381,6 +2473,13 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
}
|
||||
|
||||
auth->peer_version = 1; /* default to the first version */
|
||||
version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
|
||||
&version_len);
|
||||
if (version && version_len >= 1 && version[0] >= 2) {
|
||||
auth->peer_version = version[0];
|
||||
wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
|
||||
auth->peer_version);
|
||||
}
|
||||
|
||||
status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
|
||||
&status_len);
|
||||
@@ -3070,7 +3169,7 @@ static int dpp_configuration_parse(struct dpp_authentication *auth,
|
||||
goto fail;
|
||||
os_memcpy(tmp, cmd, len);
|
||||
tmp[len] = '\0';
|
||||
res = dpp_configuration_parse_helper(auth, cmd, 0);
|
||||
res = dpp_configuration_parse_helper(auth, tmp, 0);
|
||||
str_clear_free(tmp);
|
||||
if (res)
|
||||
goto fail;
|
||||
@@ -3080,9 +3179,13 @@ static int dpp_configuration_parse(struct dpp_authentication *auth,
|
||||
return 0;
|
||||
fail:
|
||||
dpp_configuration_free(auth->conf_sta);
|
||||
auth->conf_sta = NULL;
|
||||
dpp_configuration_free(auth->conf2_sta);
|
||||
auth->conf2_sta = NULL;
|
||||
dpp_configuration_free(auth->conf_ap);
|
||||
auth->conf_ap = NULL;
|
||||
dpp_configuration_free(auth->conf2_ap);
|
||||
auth->conf2_ap = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3160,13 +3263,19 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
||||
wpabuf_free(auth->resp_msg);
|
||||
wpabuf_free(auth->conf_req);
|
||||
for (i = 0; i < auth->num_conf_obj; i++) {
|
||||
struct dpp_config_obj *conf = &auth->conf_obj[i];
|
||||
struct dpp_config_obj *conf = &auth->conf_obj[i];
|
||||
|
||||
os_free(conf->connector);
|
||||
wpabuf_free(conf->c_sign_key);
|
||||
if (conf->connector) {
|
||||
bin_clear_free(conf->connector, os_strlen(conf->connector));
|
||||
conf->connector = NULL;
|
||||
}
|
||||
wpabuf_clear_free(conf->c_sign_key);
|
||||
conf->c_sign_key = NULL;
|
||||
}
|
||||
wpabuf_free(auth->net_access_key);
|
||||
wpabuf_clear_free(auth->net_access_key);
|
||||
auth->net_access_key = NULL;
|
||||
dpp_bootstrap_info_free(auth->tmp_own_bi);
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
os_free(auth->config_obj_override);
|
||||
os_free(auth->discovery_override);
|
||||
@@ -4809,6 +4918,8 @@ static int dpp_connector_match_groups(struct json_token *own_root,
|
||||
}
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: No compatible group found in peer connector");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "crypto/sha256.h"
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_dpp.h"
|
||||
#include "crypto/crypto.h"
|
||||
@@ -64,17 +65,6 @@ static const u8 TRANSACTION_ID = 1;
|
||||
#define DPP_EVENT_INTRO "DPP-INTRO "
|
||||
#define DPP_EVENT_CONF_REQ_RX "DPP-CONF-REQ-RX "
|
||||
|
||||
|
||||
#define WLAN_ACTION_PUBLIC 4
|
||||
#define WLAN_PA_VENDOR_SPECIFIC 9
|
||||
#define OUI_WFA 0x506f9a
|
||||
#define DPP_OUI_TYPE 0x1A
|
||||
|
||||
#define WLAN_EID_ADV_PROTO 108
|
||||
#define WLAN_EID_VENDOR_SPECIFIC 221
|
||||
|
||||
#define WLAN_PA_GAS_INITIAL_REQ 10
|
||||
|
||||
enum dpp_public_action_frame_type {
|
||||
DPP_PA_AUTHENTICATION_REQ = 0,
|
||||
DPP_PA_AUTHENTICATION_RESP = 1,
|
||||
@@ -234,7 +224,23 @@ struct dpp_configuration {
|
||||
int psk_set;
|
||||
};
|
||||
|
||||
#define DPP_MAX_CONF_OBJ 10
|
||||
#define DPP_MAX_CONF_OBJ ESP_DPP_MAX_CONFIG_COUNT
|
||||
|
||||
struct dpp_conf {
|
||||
char *connector;
|
||||
struct wpabuf *c_sign_key;
|
||||
size_t dpp_csign_len;
|
||||
struct wpabuf *net_access_key;
|
||||
os_time_t net_access_key_expiry;
|
||||
uint8_t curr_chan;
|
||||
enum dpp_akm akm;
|
||||
};
|
||||
|
||||
struct dpp_config_store {
|
||||
/* Single active DPP config used for Network Introduction; applications own multi-config selection. */
|
||||
struct dpp_conf *conf;
|
||||
u8 peer_mac_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct dpp_authentication {
|
||||
void *msg_ctx;
|
||||
@@ -511,9 +517,10 @@ struct wpabuf * dpp_build_conn_status_result(struct dpp_authentication *auth,
|
||||
enum dpp_status_error result,
|
||||
const u8 *ssid, size_t ssid_len,
|
||||
const char *channel_list);
|
||||
struct wpabuf * dpp_build_peer_disc_req(struct dpp_authentication *auth, struct dpp_config_obj *conf);
|
||||
struct wpabuf * dpp_build_peer_disc_req(struct dpp_config_store *dc, struct dpp_conf *conf);
|
||||
struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,
|
||||
size_t len);
|
||||
struct wpabuf * gas_build_comeback_req(u8 dialog_token);
|
||||
const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len);
|
||||
int dpp_check_attrs(const u8 *buf, size_t len);
|
||||
int dpp_key_expired(const char *timestamp, os_time_t *expiry);
|
||||
@@ -593,6 +600,9 @@ struct dpp_global_config {
|
||||
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
|
||||
};
|
||||
|
||||
struct dpp_config_store * dpp_config_store_init(void);
|
||||
void dpp_clear_confs(struct dpp_conf *conf);
|
||||
void dpp_config_store_deinit(struct dpp_config_store *dc);
|
||||
struct dpp_global * dpp_global_init(struct dpp_global_config *config);
|
||||
void dpp_global_clear(struct dpp_global *dpp);
|
||||
void dpp_global_deinit(struct dpp_global *dpp);
|
||||
|
||||
@@ -237,6 +237,7 @@
|
||||
#define WLAN_EID_20_40_BSS_INTOLERANT 73
|
||||
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
||||
#define WLAN_EID_MMIE 76
|
||||
#define WLAN_EID_ADV_PROTO 108
|
||||
#define WLAN_EID_EXT_CAPAB 127
|
||||
#define WLAN_EID_MIC 140
|
||||
#define WLAN_EID_VENDOR_SPECIFIC 221
|
||||
|
||||
@@ -2667,6 +2667,10 @@ int wpa_set_bss(uint8_t *macddr, uint8_t *bssid, uint8_t pairwise_cipher, uint8_
|
||||
use_pmk_cache = false;
|
||||
}
|
||||
|
||||
if (sm->key_mgmt == WPA_KEY_MGMT_DPP) {
|
||||
use_pmk_cache = true;
|
||||
}
|
||||
|
||||
if (os_memcmp(sm->ssid, ssid, ssid_len) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "reassoc same ess and okc is %d", sm->okc);
|
||||
if (sm->okc == 1) {
|
||||
|
||||
Reference in New Issue
Block a user