wpa: Redo import wpa_supplicant/hostapd commit 14ab4a816
This is the November update to vendor/wpa committed upstream 2021-11-26. MFC after: 1 month
This commit is contained in:
parent
2dfc1f7355
commit
4b72b91a71
@ -13,6 +13,7 @@
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/uuid.h"
|
||||
#include "utils/crc32.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/sae.h"
|
||||
#include "crypto/sha256.h"
|
||||
@ -2396,16 +2397,19 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||
wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
|
||||
line);
|
||||
} else if (os_strcmp(buf, "ssid") == 0) {
|
||||
bss->ssid.ssid_len = os_strlen(pos);
|
||||
if (bss->ssid.ssid_len > SSID_MAX_LEN ||
|
||||
bss->ssid.ssid_len < 1) {
|
||||
struct hostapd_ssid *ssid = &bss->ssid;
|
||||
|
||||
ssid->ssid_len = os_strlen(pos);
|
||||
if (ssid->ssid_len > SSID_MAX_LEN || ssid->ssid_len < 1) {
|
||||
wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
|
||||
line, pos);
|
||||
return 1;
|
||||
}
|
||||
os_memcpy(bss->ssid.ssid, pos, bss->ssid.ssid_len);
|
||||
bss->ssid.ssid_set = 1;
|
||||
os_memcpy(ssid->ssid, pos, ssid->ssid_len);
|
||||
ssid->ssid_set = 1;
|
||||
ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
|
||||
} else if (os_strcmp(buf, "ssid2") == 0) {
|
||||
struct hostapd_ssid *ssid = &bss->ssid;
|
||||
size_t slen;
|
||||
char *str = wpa_config_parse_string(pos, &slen);
|
||||
if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
|
||||
@ -2414,9 +2418,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||
os_free(str);
|
||||
return 1;
|
||||
}
|
||||
os_memcpy(bss->ssid.ssid, str, slen);
|
||||
bss->ssid.ssid_len = slen;
|
||||
bss->ssid.ssid_set = 1;
|
||||
os_memcpy(ssid->ssid, str, slen);
|
||||
ssid->ssid_len = slen;
|
||||
ssid->ssid_set = 1;
|
||||
ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
|
||||
os_free(str);
|
||||
} else if (os_strcmp(buf, "utf8_ssid") == 0) {
|
||||
bss->ssid.utf8_ssid = atoi(pos) > 0;
|
||||
@ -3515,6 +3520,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||
conf->he_op.he_twt_responder = atoi(pos);
|
||||
} else if (os_strcmp(buf, "he_rts_threshold") == 0) {
|
||||
conf->he_op.he_rts_threshold = atoi(pos);
|
||||
} else if (os_strcmp(buf, "he_er_su_disable") == 0) {
|
||||
conf->he_op.he_er_su_disable = atoi(pos);
|
||||
} else if (os_strcmp(buf, "he_basic_mcs_nss_set") == 0) {
|
||||
conf->he_op.he_basic_mcs_nss_set = atoi(pos);
|
||||
} else if (os_strcmp(buf, "he_mu_edca_qos_info_param_count") == 0) {
|
||||
@ -4705,6 +4712,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||
if (get_hex_config(bss->ext_capa, EXT_CAPA_MAX_LEN,
|
||||
line, "ext_capa", pos))
|
||||
return 1;
|
||||
} else if (os_strcmp(buf, "rnr") == 0) {
|
||||
bss->rnr = atoi(pos);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Line %d: unknown configuration item '%s'",
|
||||
|
@ -840,7 +840,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
|
||||
const char *pos, *end;
|
||||
int disassoc_timer = 0;
|
||||
struct sta_info *sta;
|
||||
u8 req_mode = 0, valid_int = 0x01;
|
||||
u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01;
|
||||
u8 bss_term_dur[12];
|
||||
char *url = NULL;
|
||||
int ret;
|
||||
@ -878,6 +878,12 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
|
||||
valid_int = atoi(pos);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, " dialog_token=");
|
||||
if (pos) {
|
||||
pos += 14;
|
||||
dialog_token = atoi(pos);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, " bss_term=");
|
||||
if (pos) {
|
||||
pos += 10;
|
||||
@ -984,7 +990,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
|
||||
#endif /* CONFIG_MBO */
|
||||
|
||||
ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
|
||||
valid_int, bss_term_dur, url,
|
||||
valid_int, bss_term_dur, dialog_token, url,
|
||||
nei_len ? nei_rep : NULL, nei_len,
|
||||
mbo_len ? mbo : NULL, mbo_len);
|
||||
#ifdef CONFIG_MBO
|
||||
@ -1455,10 +1461,10 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
|
||||
wps_version_number & 0x0f);
|
||||
hostapd_wps_update_ie(hapd);
|
||||
}
|
||||
} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
|
||||
wps_testing_dummy_cred = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
|
||||
wps_testing_dummy_cred);
|
||||
} else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
|
||||
wps_testing_stub_cred = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
|
||||
wps_testing_stub_cred);
|
||||
} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
|
||||
wps_corrupt_pkhash = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
|
||||
@ -3185,8 +3191,9 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct wpabuf *nr, *lci = NULL, *civic = NULL;
|
||||
int stationary = 0;
|
||||
int bss_parameters = 0;
|
||||
char *tmp;
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (!(hapd->conf->radio_measurements[0] &
|
||||
WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
|
||||
@ -3240,8 +3247,7 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
|
||||
if (!lci) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"CTRL: SET_NEIGHBOR: Bad LCI subelement");
|
||||
wpabuf_free(nr);
|
||||
return -1;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3257,9 +3263,7 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
|
||||
if (!civic) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"CTRL: SET_NEIGHBOR: Bad civic subelement");
|
||||
wpabuf_free(nr);
|
||||
wpabuf_free(lci);
|
||||
return -1;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3269,10 +3273,21 @@ static int hostapd_ctrl_iface_set_neighbor(struct hostapd_data *hapd, char *buf)
|
||||
if (os_strstr(buf, "stat"))
|
||||
stationary = 1;
|
||||
|
||||
tmp = os_strstr(buf, "bss_parameter=");
|
||||
if (tmp) {
|
||||
bss_parameters = atoi(tmp + 14);
|
||||
if (bss_parameters < 0 || bss_parameters > 0xff) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"CTRL: SET_NEIGHBOR: Bad bss_parameters subelement");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
set:
|
||||
ret = hostapd_neighbor_set(hapd, bssid, &ssid, nr, lci, civic,
|
||||
stationary);
|
||||
stationary, bss_parameters);
|
||||
|
||||
fail:
|
||||
wpabuf_free(nr);
|
||||
wpabuf_free(lci);
|
||||
wpabuf_free(civic);
|
||||
@ -4470,7 +4485,7 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
|
||||
{
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
wps_version_number = 0x20;
|
||||
wps_testing_dummy_cred = 0;
|
||||
wps_testing_stub_cred = 0;
|
||||
wps_corrupt_pkhash = 0;
|
||||
#endif /* CONFIG_WPS_TESTING */
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# 4.3.20 Test Set 20. SQN is the last used SQN value.
|
||||
# These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
|
||||
# authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
|
||||
# dummy values will need to be included in this file.
|
||||
# stub values will need to be included in this file.
|
||||
|
||||
# IMSI Ki OPc AMF SQN [RES_len]
|
||||
232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
|
||||
|
@ -841,6 +841,11 @@ wmm_ac_vo_acm=0
|
||||
# unsigned integer = duration in units of 16 us
|
||||
#he_rts_threshold=0
|
||||
|
||||
#he_er_su_disable: Disable 242-tone HE ER SU PPDU reception by the AP
|
||||
# 0 = enable reception (default)
|
||||
# 1 = disable reception
|
||||
#he_er_su_disable=0
|
||||
|
||||
# HE operating channel information; see matching vht_* parameters for details.
|
||||
# he_oper_centr_freq_seg0_idx field is used to indicate center frequency of 80
|
||||
# and 160 MHz bandwidth operation. In 80+80 MHz operation, it is the center
|
||||
@ -1832,7 +1837,7 @@ own_ip_addr=127.0.0.1
|
||||
#assoc_sa_query_retry_timeout=201
|
||||
|
||||
# ocv: Operating Channel Validation
|
||||
# This is a countermeasure against multi-channel man-in-the-middle attacks.
|
||||
# This is a countermeasure against multi-channel on-path attacks.
|
||||
# Enabling this depends on the driver's support for OCV when the driver SME is
|
||||
# used. If hostapd SME is used, this will be enabled just based on this
|
||||
# configuration.
|
||||
@ -2916,6 +2921,9 @@ own_ip_addr=127.0.0.1
|
||||
# that allows sending of such data. Default: 0.
|
||||
#stationary_ap=0
|
||||
|
||||
# Enable reduced neighbor reporting (RNR)
|
||||
#rnr=0
|
||||
|
||||
##### Airtime policy configuration ###########################################
|
||||
|
||||
# Set the airtime policy operating mode:
|
||||
|
@ -1048,7 +1048,7 @@ static char ** hostapd_complete_set(const char *str, int pos)
|
||||
int arg = get_cmd_arg_num(str, pos);
|
||||
const char *fields[] = {
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
"wps_version_number", "wps_testing_dummy_cred",
|
||||
"wps_version_number", "wps_testing_stub_cred",
|
||||
"wps_corrupt_pkhash",
|
||||
#endif /* CONFIG_WPS_TESTING */
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
|
@ -309,8 +309,6 @@ acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
|
||||
else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX)
|
||||
busy = survey->channel_time_rx;
|
||||
else {
|
||||
/* This shouldn't really happen as survey data is checked in
|
||||
* acs_sanity_check() */
|
||||
wpa_printf(MSG_ERROR, "ACS: Survey data missing");
|
||||
return 0;
|
||||
}
|
||||
@ -392,7 +390,7 @@ static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
|
||||
|
||||
static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
|
||||
{
|
||||
const int allowed[] = { 5180, 5260, 5550, 5580, 5660, 5745, 5955, 6035,
|
||||
const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
|
||||
6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
|
||||
6755, 6835, 6915, 6995 };
|
||||
unsigned int i;
|
||||
|
@ -273,7 +273,7 @@ struct hostapd_config * hostapd_config_defaults(void)
|
||||
conf->he_op.he_basic_mcs_nss_set = 0xfffc;
|
||||
conf->he_op.he_bss_color_disabled = 1;
|
||||
conf->he_op.he_bss_color_partial = 0;
|
||||
conf->he_op.he_bss_color = 1;
|
||||
conf->he_op.he_bss_color = os_random() % 63 + 1;
|
||||
conf->he_op.he_twt_responder = 1;
|
||||
conf->he_6ghz_max_mpdu = 2;
|
||||
conf->he_6ghz_max_ampdu_len_exp = 7;
|
||||
@ -1423,6 +1423,15 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
|
||||
}
|
||||
#endif /* CONFIG_SAE_PK */
|
||||
|
||||
#ifdef CONFIG_FILS
|
||||
if (full_config && bss->fils_discovery_min_int &&
|
||||
bss->unsol_bcast_probe_resp_interval) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Cannot enable both FILS discovery and unsolicited broadcast Probe Response at the same time");
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -894,6 +894,8 @@ struct hostapd_bss_config {
|
||||
|
||||
u8 ext_capa_mask[EXT_CAPA_MAX_LEN];
|
||||
u8 ext_capa[EXT_CAPA_MAX_LEN];
|
||||
|
||||
u8 rnr;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -916,6 +918,7 @@ struct he_operation {
|
||||
u8 he_twt_required;
|
||||
u8 he_twt_responder;
|
||||
u16 he_rts_threshold;
|
||||
u8 he_er_su_disable;
|
||||
u16 he_basic_mcs_nss_set;
|
||||
};
|
||||
|
||||
|
@ -469,6 +469,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
|
||||
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
|
||||
buflen += hostapd_mbo_ie_len(hapd);
|
||||
buflen += hostapd_eid_owe_trans_len(hapd);
|
||||
buflen += hostapd_eid_dpp_cc_len(hapd);
|
||||
@ -573,6 +574,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
(hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
|
||||
pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
|
||||
|
||||
pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP);
|
||||
pos = hostapd_eid_fils_indic(hapd, pos, 0);
|
||||
pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
|
||||
|
||||
@ -642,7 +644,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
enum ssid_match_result {
|
||||
NO_SSID_MATCH,
|
||||
EXACT_SSID_MATCH,
|
||||
WILDCARD_SSID_MATCH
|
||||
WILDCARD_SSID_MATCH,
|
||||
CO_LOCATED_SSID_MATCH,
|
||||
};
|
||||
|
||||
static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
|
||||
@ -653,7 +656,9 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
|
||||
size_t short_ssid_list_len)
|
||||
{
|
||||
const u8 *pos, *end;
|
||||
struct hostapd_iface *iface = hapd->iface;
|
||||
int wildcard = 0;
|
||||
size_t i, j;
|
||||
|
||||
if (ssid_len == 0)
|
||||
wildcard = 1;
|
||||
@ -687,7 +692,33 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
|
||||
}
|
||||
}
|
||||
|
||||
return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
|
||||
if (wildcard)
|
||||
return WILDCARD_SSID_MATCH;
|
||||
|
||||
if (!iface->interfaces || iface->interfaces->count <= 1 ||
|
||||
is_6ghz_op_class(hapd->iconf->op_class))
|
||||
return NO_SSID_MATCH;
|
||||
|
||||
for (i = 0; i < iface->interfaces->count; i++) {
|
||||
struct hostapd_iface *colocated;
|
||||
|
||||
colocated = iface->interfaces->iface[i];
|
||||
|
||||
if (colocated == iface ||
|
||||
!is_6ghz_op_class(colocated->conf->op_class))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < colocated->num_bss; j++) {
|
||||
struct hostapd_bss_config *conf;
|
||||
|
||||
conf = colocated->bss[j]->conf;
|
||||
if (ssid_len == conf->ssid.ssid_len &&
|
||||
os_memcmp(ssid, conf->ssid.ssid, ssid_len) == 0)
|
||||
return CO_LOCATED_SSID_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return NO_SSID_MATCH;
|
||||
}
|
||||
|
||||
|
||||
@ -1284,6 +1315,8 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
|
||||
total_len += 3;
|
||||
}
|
||||
|
||||
total_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_ACTION);
|
||||
|
||||
pos = hostapd_eid_fils_indic(hapd, buf, 0);
|
||||
buf_len = pos - buf;
|
||||
total_len += buf_len;
|
||||
@ -1352,6 +1385,8 @@ static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
|
||||
/* Fill in the Length field value */
|
||||
*length_pos = pos - (length_pos + 1);
|
||||
|
||||
pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_ACTION);
|
||||
|
||||
/* FILS Indication element */
|
||||
if (buf_len) {
|
||||
os_memcpy(pos, buf, buf_len);
|
||||
@ -1438,6 +1473,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
|
||||
tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
|
||||
tail_len += hostapd_mbo_ie_len(hapd);
|
||||
tail_len += hostapd_eid_owe_trans_len(hapd);
|
||||
tail_len += hostapd_eid_dpp_cc_len(hapd);
|
||||
@ -1562,6 +1598,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||
(hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
|
||||
tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
|
||||
|
||||
tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON);
|
||||
tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
|
||||
tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
|
||||
|
||||
@ -1743,7 +1780,7 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
|
||||
}
|
||||
|
||||
|
||||
int ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wpa_driver_ap_params params;
|
||||
struct hostapd_freq_params freq;
|
||||
@ -1832,6 +1869,42 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
}
|
||||
|
||||
|
||||
int ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||
{
|
||||
struct hostapd_iface *iface = hapd->iface;
|
||||
int ret;
|
||||
size_t i, j;
|
||||
bool is_6g;
|
||||
|
||||
ret = __ieee802_11_set_beacon(hapd);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (!iface->interfaces || iface->interfaces->count <= 1)
|
||||
return 0;
|
||||
|
||||
/* Update Beacon frames in case of 6 GHz colocation */
|
||||
is_6g = is_6ghz_op_class(iface->conf->op_class);
|
||||
for (j = 0; j < iface->interfaces->count; j++) {
|
||||
struct hostapd_iface *colocated;
|
||||
|
||||
colocated = iface->interfaces->iface[j];
|
||||
if (colocated == iface || !colocated || !colocated->conf)
|
||||
continue;
|
||||
|
||||
if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < colocated->num_bss; i++) {
|
||||
if (colocated->bss[i] && colocated->bss[i]->started)
|
||||
__ieee802_11_set_beacon(colocated->bss[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ieee802_11_set_beacons(struct hostapd_iface *iface)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -50,9 +50,35 @@ static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
static int hostapd_get_sta_conn_time(struct sta_info *sta,
|
||||
struct hostap_sta_driver_data *data,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
struct os_reltime age;
|
||||
unsigned long secs;
|
||||
int ret;
|
||||
|
||||
if (sta->connected_time.sec) {
|
||||
/* Locally maintained time in AP mode */
|
||||
os_reltime_age(&sta->connected_time, &age);
|
||||
secs = (unsigned long) age.sec;
|
||||
} else if (data->flags & STA_DRV_DATA_CONN_TIME) {
|
||||
/* Time from the driver in mesh mode */
|
||||
secs = data->connected_sec;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = os_snprintf(buf, buflen, "connected_time=%lu\n", secs);
|
||||
if (os_snprintf_error(buflen, ret))
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_get_sta_info(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
struct hostap_sta_driver_data data;
|
||||
int ret;
|
||||
@ -160,29 +186,12 @@ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
|
||||
len += ret;
|
||||
}
|
||||
|
||||
len += hostapd_get_sta_conn_time(sta, &data, buf + len, buflen - len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static int hostapd_get_sta_conn_time(struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
struct os_reltime age;
|
||||
int ret;
|
||||
|
||||
if (!sta->connected_time.sec)
|
||||
return 0;
|
||||
|
||||
os_reltime_age(&sta->connected_time, &age);
|
||||
|
||||
ret = os_snprintf(buf, buflen, "connected_time=%u\n",
|
||||
(unsigned int) age.sec);
|
||||
if (os_snprintf_error(buflen, ret))
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static const char * timeout_next_str(int val)
|
||||
{
|
||||
switch (val) {
|
||||
@ -263,8 +272,7 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
|
||||
if (res >= 0)
|
||||
len += res;
|
||||
|
||||
len += hostapd_get_sta_tx_rx(hapd, sta, buf + len, buflen - len);
|
||||
len += hostapd_get_sta_conn_time(sta, buf + len, buflen - len);
|
||||
len += hostapd_get_sta_info(hapd, sta, buf + len, buflen - len);
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
if (sta->sae && sta->sae->state == SAE_ACCEPTED) {
|
||||
|
@ -88,6 +88,7 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) {
|
||||
for (sta = hapd->sta_list; sta; sta = sta->next) {
|
||||
if (!(sta->flags & WLAN_STA_AUTHORIZED))
|
||||
@ -96,6 +97,7 @@ static void handle_dhcp(void *ctx, const u8 *src_addr, const u8 *buf,
|
||||
(u8 *) buf, len);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
if (msgtype == DHCPACK) {
|
||||
if (b->your_ip == 0)
|
||||
|
@ -2276,6 +2276,8 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
|
||||
eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
|
||||
NULL);
|
||||
hostapd_dpp_chirp_stop(hapd);
|
||||
if (hapd->iface->interfaces)
|
||||
dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
|
||||
#endif /* CONFIG_DPP2 */
|
||||
dpp_auth_deinit(hapd->dpp_auth);
|
||||
hapd->dpp_auth = NULL;
|
||||
@ -2387,6 +2389,7 @@ hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
|
||||
unsigned int i;
|
||||
struct hostapd_hw_modes *mode;
|
||||
int c;
|
||||
bool chan6 = hapd->iface->hw_features == NULL;
|
||||
|
||||
if (!bi)
|
||||
return;
|
||||
@ -2406,7 +2409,21 @@ hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
|
||||
}
|
||||
|
||||
/* Preferred chirping channels */
|
||||
int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
|
||||
mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
|
||||
if (mode) {
|
||||
for (c = 0; c < mode->num_channels; c++) {
|
||||
struct hostapd_channel_data *chan = &mode->channels[c];
|
||||
|
||||
if (chan->flag & (HOSTAPD_CHAN_DISABLED |
|
||||
HOSTAPD_CHAN_RADAR) ||
|
||||
chan->freq != 2437)
|
||||
continue;
|
||||
chan6 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chan6)
|
||||
int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
|
||||
|
||||
mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
|
||||
if (mode) {
|
||||
|
@ -138,6 +138,8 @@ struct hostapd_neighbor_entry {
|
||||
/* LCI update time */
|
||||
struct os_time lci_date;
|
||||
int stationary;
|
||||
u32 short_ssid;
|
||||
u8 bss_parameters;
|
||||
};
|
||||
|
||||
struct hostapd_sae_commit_queue {
|
||||
|
@ -838,6 +838,8 @@ static int hostapd_is_usable_edmg(struct hostapd_iface *iface)
|
||||
iface->freq, NULL,
|
||||
iface->hw_features,
|
||||
iface->num_hw_features);
|
||||
if (!pri_chan)
|
||||
return 0;
|
||||
hostapd_encode_edmg_chan(iface->conf->enable_edmg,
|
||||
iface->conf->edmg_channel,
|
||||
pri_chan->chan,
|
||||
|
@ -2398,7 +2398,7 @@ static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
|
||||
buf_len = wpabuf_len(wd);
|
||||
|
||||
if (buf_len < 6) {
|
||||
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%lu",
|
||||
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
|
||||
buf_len);
|
||||
return -1;
|
||||
}
|
||||
@ -2474,7 +2474,7 @@ static int pasn_wd_handle_sae_confirm(struct hostapd_data *hapd,
|
||||
buf_len = wpabuf_len(wd);
|
||||
|
||||
if (buf_len < 6) {
|
||||
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%lu",
|
||||
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
|
||||
buf_len);
|
||||
return -1;
|
||||
}
|
||||
@ -2704,7 +2704,7 @@ static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
buf_len = wpabuf_len(wd);
|
||||
|
||||
if (buf_len < 6) {
|
||||
wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%lu",
|
||||
wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%zu",
|
||||
buf_len);
|
||||
return -1;
|
||||
}
|
||||
@ -7071,4 +7071,386 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_neighbor_entry *nr;
|
||||
size_t total_len = 0, len = *current_len;
|
||||
|
||||
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
|
||||
list) {
|
||||
if (!nr->nr || wpabuf_len(nr->nr) < 12)
|
||||
continue;
|
||||
|
||||
if (nr->short_ssid == hapd->conf->ssid.short_ssid)
|
||||
continue;
|
||||
|
||||
/* Start a new element */
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
len = RNR_HEADER_LEN;
|
||||
total_len += RNR_HEADER_LEN;
|
||||
}
|
||||
|
||||
len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
|
||||
total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
|
||||
}
|
||||
|
||||
*current_len = len;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
||||
static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
||||
struct hostapd_data *reporting_hapd,
|
||||
size_t *current_len)
|
||||
{
|
||||
size_t total_len = 0, len = *current_len;
|
||||
int tbtt_count = 0;
|
||||
size_t i, start = 0;
|
||||
|
||||
while (start < hapd->iface->num_bss) {
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
len = RNR_HEADER_LEN;
|
||||
total_len += RNR_HEADER_LEN;
|
||||
}
|
||||
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
total_len += RNR_TBTT_HEADER_LEN;
|
||||
|
||||
for (i = start; i < hapd->iface->num_bss; i++) {
|
||||
struct hostapd_data *bss = hapd->iface->bss[i];
|
||||
|
||||
if (!bss || !bss->conf || !bss->started)
|
||||
continue;
|
||||
|
||||
if (bss == reporting_hapd ||
|
||||
bss->conf->ignore_broadcast_ssid)
|
||||
continue;
|
||||
|
||||
if (len + RNR_TBTT_INFO_LEN > 255 ||
|
||||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
|
||||
break;
|
||||
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
total_len += RNR_TBTT_INFO_LEN;
|
||||
tbtt_count++;
|
||||
}
|
||||
start = i;
|
||||
}
|
||||
|
||||
if (!tbtt_count)
|
||||
total_len = 0;
|
||||
else
|
||||
*current_len = len;
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
||||
enum colocation_mode {
|
||||
NO_COLOCATED_6GHZ,
|
||||
STANDALONE_6GHZ,
|
||||
COLOCATED_6GHZ,
|
||||
COLOCATED_LOWER_BAND,
|
||||
};
|
||||
|
||||
static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
|
||||
{
|
||||
u8 i;
|
||||
bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
|
||||
|
||||
if (!hapd->iface || !hapd->iface->interfaces)
|
||||
return NO_COLOCATED_6GHZ;
|
||||
|
||||
if (is_6ghz && hapd->iface->interfaces->count == 1)
|
||||
return STANDALONE_6GHZ;
|
||||
|
||||
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
struct hostapd_iface *iface;
|
||||
bool is_colocated_6ghz;
|
||||
|
||||
iface = hapd->iface->interfaces->iface[i];
|
||||
if (iface == hapd->iface || !iface || !iface->conf)
|
||||
continue;
|
||||
|
||||
is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
|
||||
if (!is_6ghz && is_colocated_6ghz)
|
||||
return COLOCATED_LOWER_BAND;
|
||||
if (is_6ghz && !is_colocated_6ghz)
|
||||
return COLOCATED_6GHZ;
|
||||
}
|
||||
|
||||
if (is_6ghz)
|
||||
return STANDALONE_6GHZ;
|
||||
|
||||
return NO_COLOCATED_6GHZ;
|
||||
}
|
||||
|
||||
|
||||
static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_iface *iface;
|
||||
size_t len = 0;
|
||||
size_t i;
|
||||
|
||||
if (!hapd->iface || !hapd->iface->interfaces)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
iface = hapd->iface->interfaces->iface[i];
|
||||
|
||||
if (iface == hapd->iface ||
|
||||
!is_6ghz_op_class(iface->conf->op_class))
|
||||
continue;
|
||||
|
||||
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
|
||||
current_len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
||||
{
|
||||
size_t total_len = 0, current_len = 0;
|
||||
enum colocation_mode mode = get_colocation_mode(hapd);
|
||||
|
||||
switch (type) {
|
||||
case WLAN_FC_STYPE_BEACON:
|
||||
if (hapd->conf->rnr)
|
||||
total_len += hostapd_eid_nr_db_len(hapd, ¤t_len);
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (mode == COLOCATED_LOWER_BAND)
|
||||
total_len += hostapd_eid_rnr_colocation_len(
|
||||
hapd, ¤t_len);
|
||||
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
|
||||
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
case WLAN_FC_STYPE_ACTION:
|
||||
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
|
||||
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
||||
static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_neighbor_entry *nr;
|
||||
size_t len = *current_len;
|
||||
u8 *size_offset = (eid - len) + 1;
|
||||
|
||||
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
|
||||
list) {
|
||||
if (!nr->nr || wpabuf_len(nr->nr) < 12)
|
||||
continue;
|
||||
|
||||
if (nr->short_ssid == hapd->conf->ssid.short_ssid)
|
||||
continue;
|
||||
|
||||
/* Start a new element */
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
|
||||
size_offset = eid++;
|
||||
len = RNR_HEADER_LEN;
|
||||
}
|
||||
|
||||
/* TBTT Information Header subfield (2 octets) */
|
||||
*eid++ = 0;
|
||||
/* TBTT Information Length */
|
||||
*eid++ = RNR_TBTT_INFO_LEN;
|
||||
/* Operating Class */
|
||||
*eid++ = wpabuf_head_u8(nr->nr)[10];
|
||||
/* Channel Number */
|
||||
*eid++ = wpabuf_head_u8(nr->nr)[11];
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
/* TBTT Information Set */
|
||||
/* TBTT Information field */
|
||||
/* Neighbor AP TBTT Offset */
|
||||
*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
|
||||
/* BSSID */
|
||||
os_memcpy(eid, nr->bssid, ETH_ALEN);
|
||||
eid += ETH_ALEN;
|
||||
/* Short SSID */
|
||||
os_memcpy(eid, &nr->short_ssid, 4);
|
||||
eid += 4;
|
||||
/* BSS parameters */
|
||||
*eid++ = nr->bss_parameters;
|
||||
/* 20 MHz PSD */
|
||||
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
*size_offset = (eid - size_offset) - 1;
|
||||
}
|
||||
|
||||
*current_len = len;
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
||||
struct hostapd_data *reporting_hapd,
|
||||
u8 *eid, size_t *current_len)
|
||||
{
|
||||
struct hostapd_data *bss;
|
||||
struct hostapd_iface *iface = hapd->iface;
|
||||
size_t i, start = 0;
|
||||
size_t len = *current_len;
|
||||
u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
|
||||
u8 tbtt_count = 0, op_class, channel, bss_param;
|
||||
|
||||
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
|
||||
return eid;
|
||||
|
||||
if (ieee80211_freq_to_channel_ext(iface->freq,
|
||||
hapd->iconf->secondary_channel,
|
||||
hostapd_get_oper_chwidth(hapd->iconf),
|
||||
&op_class, &channel) ==
|
||||
NUM_HOSTAPD_MODES)
|
||||
return eid;
|
||||
|
||||
while (start < iface->num_bss) {
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
eid_start = eid;
|
||||
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
|
||||
size_offset = eid++;
|
||||
len = RNR_HEADER_LEN;
|
||||
tbtt_count = 0;
|
||||
}
|
||||
|
||||
tbtt_count_pos = eid++;
|
||||
*eid++ = RNR_TBTT_INFO_LEN;
|
||||
*eid++ = op_class;
|
||||
*eid++ = hapd->iconf->channel;
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
|
||||
for (i = start; i < iface->num_bss; i++) {
|
||||
bss_param = 0;
|
||||
bss = iface->bss[i];
|
||||
if (!bss || !bss->conf || !bss->started)
|
||||
continue;
|
||||
|
||||
if (bss == reporting_hapd ||
|
||||
bss->conf->ignore_broadcast_ssid)
|
||||
continue;
|
||||
|
||||
if (len + RNR_TBTT_INFO_LEN > 255 ||
|
||||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
|
||||
break;
|
||||
|
||||
*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
|
||||
os_memcpy(eid, bss->conf->bssid, ETH_ALEN);
|
||||
eid += ETH_ALEN;
|
||||
os_memcpy(eid, &bss->conf->ssid.short_ssid, 4);
|
||||
eid += 4;
|
||||
if (bss->conf->ssid.short_ssid ==
|
||||
reporting_hapd->conf->ssid.short_ssid)
|
||||
bss_param |= RNR_BSS_PARAM_SAME_SSID;
|
||||
|
||||
if (is_6ghz_op_class(hapd->iconf->op_class) &&
|
||||
bss->conf->unsol_bcast_probe_resp_interval)
|
||||
bss_param |=
|
||||
RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE;
|
||||
|
||||
bss_param |= RNR_BSS_PARAM_CO_LOCATED;
|
||||
|
||||
*eid++ = bss_param;
|
||||
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
tbtt_count += 1;
|
||||
}
|
||||
|
||||
start = i;
|
||||
*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
|
||||
*size_offset = (eid - size_offset) - 1;
|
||||
}
|
||||
|
||||
if (tbtt_count == 0)
|
||||
return eid_start;
|
||||
|
||||
*current_len = len;
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_iface *iface;
|
||||
size_t i;
|
||||
|
||||
if (!hapd->iface || !hapd->iface->interfaces)
|
||||
return eid;
|
||||
|
||||
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
iface = hapd->iface->interfaces->iface[i];
|
||||
|
||||
if (iface == hapd->iface ||
|
||||
!is_6ghz_op_class(iface->conf->op_class))
|
||||
continue;
|
||||
|
||||
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
|
||||
current_len);
|
||||
}
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
||||
{
|
||||
u8 *eid_start = eid;
|
||||
size_t current_len = 0;
|
||||
enum colocation_mode mode = get_colocation_mode(hapd);
|
||||
|
||||
switch (type) {
|
||||
case WLAN_FC_STYPE_BEACON:
|
||||
if (hapd->conf->rnr)
|
||||
eid = hostapd_eid_nr_db(hapd, eid, ¤t_len);
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (mode == COLOCATED_LOWER_BAND)
|
||||
eid = hostapd_eid_rnr_colocation(hapd, eid,
|
||||
¤t_len);
|
||||
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
|
||||
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
case WLAN_FC_STYPE_ACTION:
|
||||
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
|
||||
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
return eid_start;
|
||||
}
|
||||
|
||||
if (eid == eid_start + 2)
|
||||
return eid_start;
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
@ -194,5 +194,7 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
|
||||
|
||||
void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
|
||||
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
|
||||
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
|
||||
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
|
||||
|
||||
#endif /* IEEE802_11_H */
|
||||
|
@ -192,6 +192,9 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
|
||||
params |= (hapd->iface->conf->he_op.he_rts_threshold <<
|
||||
HE_OPERATION_RTS_THRESHOLD_OFFSET);
|
||||
|
||||
if (hapd->iface->conf->he_op.he_er_su_disable)
|
||||
params |= HE_OPERATION_ER_SU_DISABLE;
|
||||
|
||||
if (hapd->iface->conf->he_op.he_bss_color_disabled)
|
||||
params |= HE_OPERATION_BSS_COLOR_DISABLED;
|
||||
if (hapd->iface->conf->he_op.he_bss_color_partial)
|
||||
|
@ -150,10 +150,12 @@ static void handle_ndisc(void *ctx, const u8 *src_addr, const u8 *buf,
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_HS20
|
||||
case ROUTER_ADVERTISEMENT:
|
||||
if (hapd->conf->disable_dgaf)
|
||||
ucast_to_stas(hapd, buf, len);
|
||||
break;
|
||||
#endif /* CONFIG_HS20 */
|
||||
case NEIGHBOR_ADVERTISEMENT:
|
||||
if (hapd->conf->na_mcast_to_ucast)
|
||||
ucast_to_stas(hapd, buf, len);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/crc32.h"
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "neighbor_db.h"
|
||||
@ -120,7 +121,8 @@ hostapd_neighbor_add(struct hostapd_data *hapd)
|
||||
int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
||||
const struct wpa_ssid_value *ssid,
|
||||
const struct wpabuf *nr, const struct wpabuf *lci,
|
||||
const struct wpabuf *civic, int stationary)
|
||||
const struct wpabuf *civic, int stationary,
|
||||
u8 bss_parameters)
|
||||
{
|
||||
struct hostapd_neighbor_entry *entry;
|
||||
|
||||
@ -134,6 +136,7 @@ int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
||||
|
||||
os_memcpy(entry->bssid, bssid, ETH_ALEN);
|
||||
os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
|
||||
entry->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
|
||||
|
||||
entry->nr = wpabuf_dup(nr);
|
||||
if (!entry->nr)
|
||||
@ -152,6 +155,7 @@ int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
||||
}
|
||||
|
||||
entry->stationary = stationary;
|
||||
entry->bss_parameters = bss_parameters;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -311,7 +315,7 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
|
||||
wpabuf_put_u8(nr, center_freq2_idx);
|
||||
|
||||
hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
|
||||
hapd->iconf->civic, hapd->iconf->stationary_ap);
|
||||
hapd->iconf->civic, hapd->iconf->stationary_ap, 0);
|
||||
|
||||
wpabuf_free(nr);
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
@ -17,7 +17,8 @@ int hostapd_neighbor_show(struct hostapd_data *hapd, char *buf, size_t buflen);
|
||||
int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
||||
const struct wpa_ssid_value *ssid,
|
||||
const struct wpabuf *nr, const struct wpabuf *lci,
|
||||
const struct wpabuf *civic, int stationary);
|
||||
const struct wpabuf *civic, int stationary,
|
||||
u8 bss_parameters);
|
||||
void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
|
||||
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
|
||||
const struct wpa_ssid_value *ssid);
|
||||
|
@ -788,8 +788,8 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
|
||||
|
||||
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u8 req_mode, int disassoc_timer, u8 valid_int,
|
||||
const u8 *bss_term_dur, const char *url,
|
||||
const u8 *nei_rep, size_t nei_rep_len,
|
||||
const u8 *bss_term_dur, u8 dialog_token,
|
||||
const char *url, const u8 *nei_rep, size_t nei_rep_len,
|
||||
const u8 *mbo_attrs, size_t mbo_len)
|
||||
{
|
||||
u8 *buf, *pos;
|
||||
@ -797,8 +797,10 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
size_t url_len;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
|
||||
MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x",
|
||||
MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int);
|
||||
MACSTR
|
||||
" req_mode=0x%x disassoc_timer=%d valid_int=0x%x dialog_token=%u",
|
||||
MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int,
|
||||
dialog_token);
|
||||
buf = os_zalloc(1000 + nei_rep_len + mbo_len);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
@ -810,7 +812,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt->u.action.category = WLAN_ACTION_WNM;
|
||||
mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
|
||||
mgmt->u.action.u.bss_tm_req.dialog_token = 1;
|
||||
mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
|
||||
mgmt->u.action.u.bss_tm_req.req_mode = req_mode;
|
||||
mgmt->u.action.u.bss_tm_req.disassoc_timer =
|
||||
host_to_le16(disassoc_timer);
|
||||
|
@ -20,8 +20,8 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
|
||||
int disassoc_timer);
|
||||
int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u8 req_mode, int disassoc_timer, u8 valid_int,
|
||||
const u8 *bss_term_dur, const char *url,
|
||||
const u8 *nei_rep, size_t nei_rep_len,
|
||||
const u8 *bss_term_dur, u8 dialog_token,
|
||||
const char *url, const u8 *nei_rep, size_t nei_rep_len,
|
||||
const u8 *mbo_attrs, size_t mbo_len);
|
||||
void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
|
@ -2742,7 +2742,7 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
|
||||
struct wpabuf *plain;
|
||||
u8 *len, *tmp, *tmp2;
|
||||
u8 hdr[2];
|
||||
u8 *gtk, dummy_gtk[32];
|
||||
u8 *gtk, stub_gtk[32];
|
||||
size_t gtk_len;
|
||||
struct wpa_group *gsm;
|
||||
size_t plain_len;
|
||||
@ -2785,11 +2785,11 @@ static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
|
||||
* Provide unique random GTK to each STA to prevent use
|
||||
* of GTK in the BSS.
|
||||
*/
|
||||
if (random_get_bytes(dummy_gtk, gtk_len) < 0) {
|
||||
if (random_get_bytes(stub_gtk, gtk_len) < 0) {
|
||||
wpabuf_clear_free(plain);
|
||||
return NULL;
|
||||
}
|
||||
gtk = dummy_gtk;
|
||||
gtk = stub_gtk;
|
||||
}
|
||||
hdr[0] = gsm->GN & 0x03;
|
||||
hdr[1] = 0;
|
||||
@ -3372,7 +3372,7 @@ static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid,
|
||||
|
||||
SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
||||
{
|
||||
u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32];
|
||||
u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, stub_gtk[32];
|
||||
size_t gtk_len, kde_len, wpa_ie_len;
|
||||
struct wpa_group *gsm = sm->group;
|
||||
u8 *wpa_ie;
|
||||
@ -3458,9 +3458,9 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
||||
* Provide unique random GTK to each STA to prevent use
|
||||
* of GTK in the BSS.
|
||||
*/
|
||||
if (random_get_bytes(dummy_gtk, gtk_len) < 0)
|
||||
if (random_get_bytes(stub_gtk, gtk_len) < 0)
|
||||
goto done;
|
||||
gtk = dummy_gtk;
|
||||
gtk = stub_gtk;
|
||||
}
|
||||
gtkidx = gsm->GN;
|
||||
_rsc = rsc;
|
||||
@ -3853,7 +3853,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
|
||||
const u8 *kde;
|
||||
u8 *kde_buf = NULL, *pos, hdr[2];
|
||||
size_t kde_len;
|
||||
u8 *gtk, dummy_gtk[32];
|
||||
u8 *gtk, stub_gtk[32];
|
||||
struct wpa_auth_config *conf = &sm->wpa_auth->conf;
|
||||
|
||||
SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
|
||||
@ -3885,9 +3885,9 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
|
||||
* Provide unique random GTK to each STA to prevent use
|
||||
* of GTK in the BSS.
|
||||
*/
|
||||
if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0)
|
||||
if (random_get_bytes(stub_gtk, gsm->GTK_len) < 0)
|
||||
return;
|
||||
gtk = dummy_gtk;
|
||||
gtk = stub_gtk;
|
||||
}
|
||||
if (sm->wpa == WPA_VERSION_WPA2) {
|
||||
kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
|
||||
|
@ -455,7 +455,7 @@ static int wpa_ft_rrb_lin(const struct tlv_list *tlvs1,
|
||||
pos += wpa_ft_tlv_lin(tlvs2, pos, endpos);
|
||||
pos += wpa_ft_vlan_lin(vlan, pos, endpos);
|
||||
|
||||
/* sanity check */
|
||||
/* validity check */
|
||||
if (pos != endpos) {
|
||||
wpa_printf(MSG_ERROR, "FT: Length error building RRB");
|
||||
goto err;
|
||||
@ -2259,7 +2259,7 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
||||
const u8 *kek, *igtk;
|
||||
size_t kek_len;
|
||||
size_t igtk_len;
|
||||
u8 dummy_igtk[WPA_IGTK_MAX_LEN];
|
||||
u8 stub_igtk[WPA_IGTK_MAX_LEN];
|
||||
|
||||
if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
|
||||
kek = sm->PTK.kek2;
|
||||
@ -2292,11 +2292,11 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
||||
* Provide unique random IGTK to each STA to prevent use of
|
||||
* IGTK in the BSS.
|
||||
*/
|
||||
if (random_get_bytes(dummy_igtk, igtk_len / 8) < 0) {
|
||||
if (random_get_bytes(stub_igtk, igtk_len / 8) < 0) {
|
||||
os_free(subelem);
|
||||
return NULL;
|
||||
}
|
||||
igtk = dummy_igtk;
|
||||
igtk = stub_igtk;
|
||||
}
|
||||
if (aes_wrap(kek, kek_len, igtk_len / 8, igtk, pos)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
@ -2319,7 +2319,7 @@ static u8 * wpa_ft_bigtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
||||
const u8 *kek, *bigtk;
|
||||
size_t kek_len;
|
||||
size_t bigtk_len;
|
||||
u8 dummy_bigtk[WPA_IGTK_MAX_LEN];
|
||||
u8 stub_bigtk[WPA_IGTK_MAX_LEN];
|
||||
|
||||
if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
|
||||
kek = sm->PTK.kek2;
|
||||
@ -2352,11 +2352,11 @@ static u8 * wpa_ft_bigtk_subelem(struct wpa_state_machine *sm, size_t *len)
|
||||
* Provide unique random BIGTK to each OSEN STA to prevent use
|
||||
* of BIGTK in the BSS.
|
||||
*/
|
||||
if (random_get_bytes(dummy_bigtk, bigtk_len / 8) < 0) {
|
||||
if (random_get_bytes(stub_bigtk, bigtk_len / 8) < 0) {
|
||||
os_free(subelem);
|
||||
return NULL;
|
||||
}
|
||||
bigtk = dummy_bigtk;
|
||||
bigtk = stub_bigtk;
|
||||
}
|
||||
if (aes_wrap(kek, kek_len, bigtk_len / 8, bigtk, pos)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
@ -3590,7 +3590,7 @@ int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
|
||||
}
|
||||
|
||||
/*
|
||||
* Do some sanity checking on the target AP address (not own and not
|
||||
* Do some validity checking on the target AP address (not own and not
|
||||
* broadcast. This could be extended to filter based on a list of known
|
||||
* APs in the MD (if such a list were configured).
|
||||
*/
|
||||
|
@ -1964,6 +1964,11 @@ int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
|
||||
cred.key_len = len / 2;
|
||||
}
|
||||
|
||||
if (!hapd->wps) {
|
||||
wpa_printf(MSG_ERROR, "WPS: WPS config does not exist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return wps_registrar_config_ap(hapd->wps->registrar, &cred);
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,6 @@
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/base64.h"
|
||||
@ -38,22 +36,6 @@ int dpp_version_override = 1;
|
||||
enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
/* Compatibility wrappers for older versions. */
|
||||
|
||||
#ifdef CONFIG_DPP2
|
||||
static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_EC)
|
||||
return NULL;
|
||||
return pkey->pkey.ec;
|
||||
}
|
||||
#endif /* CONFIG_DPP2 */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
|
||||
{
|
||||
@ -180,7 +162,7 @@ void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info)
|
||||
os_free(info->info);
|
||||
os_free(info->chan);
|
||||
os_free(info->pk);
|
||||
EVP_PKEY_free(info->pubkey);
|
||||
crypto_ec_key_deinit(info->pubkey);
|
||||
str_clear_free(info->configurator_params);
|
||||
os_free(info);
|
||||
}
|
||||
@ -1268,9 +1250,9 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
||||
dpp_configuration_free(auth->conf2_ap);
|
||||
dpp_configuration_free(auth->conf_sta);
|
||||
dpp_configuration_free(auth->conf2_sta);
|
||||
EVP_PKEY_free(auth->own_protocol_key);
|
||||
EVP_PKEY_free(auth->peer_protocol_key);
|
||||
EVP_PKEY_free(auth->reconfig_old_protocol_key);
|
||||
crypto_ec_key_deinit(auth->own_protocol_key);
|
||||
crypto_ec_key_deinit(auth->peer_protocol_key);
|
||||
crypto_ec_key_deinit(auth->reconfig_old_protocol_key);
|
||||
wpabuf_free(auth->req_msg);
|
||||
wpabuf_free(auth->resp_msg);
|
||||
wpabuf_free(auth->conf_req);
|
||||
@ -1360,14 +1342,15 @@ dpp_build_conf_start(struct dpp_authentication *auth,
|
||||
}
|
||||
|
||||
|
||||
int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
|
||||
const char *kid, const struct dpp_curve_params *curve)
|
||||
int dpp_build_jwk(struct wpabuf *buf, const char *name,
|
||||
struct crypto_ec_key *key, const char *kid,
|
||||
const struct dpp_curve_params *curve)
|
||||
{
|
||||
struct wpabuf *pub;
|
||||
const u8 *pos;
|
||||
int ret = -1;
|
||||
|
||||
pub = dpp_get_pubkey_point(key, 0);
|
||||
pub = crypto_ec_key_get_pubkey_point(key, 0);
|
||||
if (!pub)
|
||||
goto fail;
|
||||
|
||||
@ -2160,14 +2143,13 @@ static int dpp_parse_cred_legacy(struct dpp_config_obj *conf,
|
||||
}
|
||||
|
||||
|
||||
EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve)
|
||||
struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve)
|
||||
{
|
||||
struct json_token *token;
|
||||
const struct dpp_curve_params *curve;
|
||||
struct wpabuf *x = NULL, *y = NULL;
|
||||
EC_GROUP *group;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
struct crypto_ec_key *key = NULL;
|
||||
|
||||
token = json_get_member(jwk, "kty");
|
||||
if (!token || token->type != JSON_STRING) {
|
||||
@ -2220,22 +2202,18 @@ EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
|
||||
if (!group) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Could not prepare group for JWK");
|
||||
key = crypto_ec_key_set_pub(curve->ike_group, wpabuf_head(x),
|
||||
wpabuf_head(y), wpabuf_len(x));
|
||||
if (!key)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pkey = dpp_set_pubkey_point_group(group, wpabuf_head(x), wpabuf_head(y),
|
||||
wpabuf_len(x));
|
||||
EC_GROUP_free(group);
|
||||
*key_curve = curve;
|
||||
|
||||
fail:
|
||||
wpabuf_free(x);
|
||||
wpabuf_free(y);
|
||||
|
||||
return pkey;
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@ -2325,7 +2303,7 @@ static int dpp_parse_connector(struct dpp_authentication *auth,
|
||||
{
|
||||
struct json_token *root, *groups, *netkey, *token;
|
||||
int ret = -1;
|
||||
EVP_PKEY *key = NULL;
|
||||
struct crypto_ec_key *key = NULL;
|
||||
const struct dpp_curve_params *curve;
|
||||
unsigned int rules = 0;
|
||||
|
||||
@ -2392,7 +2370,7 @@ static int dpp_parse_connector(struct dpp_authentication *auth,
|
||||
goto fail;
|
||||
dpp_debug_print_key("DPP: Received netAccessKey", key);
|
||||
|
||||
if (EVP_PKEY_cmp(key, auth->own_protocol_key) != 1) {
|
||||
if (crypto_ec_key_cmp(key, auth->own_protocol_key)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: netAccessKey in connector does not match own protocol key");
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
@ -2409,47 +2387,45 @@ static int dpp_parse_connector(struct dpp_authentication *auth,
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
EVP_PKEY_free(key);
|
||||
crypto_ec_key_deinit(key);
|
||||
json_free(root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void dpp_copy_csign(struct dpp_config_obj *conf, EVP_PKEY *csign)
|
||||
static void dpp_copy_csign(struct dpp_config_obj *conf,
|
||||
struct crypto_ec_key *csign)
|
||||
{
|
||||
unsigned char *der = NULL;
|
||||
int der_len;
|
||||
struct wpabuf *c_sign_key;
|
||||
|
||||
der_len = i2d_PUBKEY(csign, &der);
|
||||
if (der_len <= 0)
|
||||
c_sign_key = crypto_ec_key_get_subject_public_key(csign);
|
||||
if (!c_sign_key)
|
||||
return;
|
||||
|
||||
wpabuf_free(conf->c_sign_key);
|
||||
conf->c_sign_key = wpabuf_alloc_copy(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
conf->c_sign_key = c_sign_key;
|
||||
}
|
||||
|
||||
|
||||
static void dpp_copy_ppkey(struct dpp_config_obj *conf, EVP_PKEY *ppkey)
|
||||
static void dpp_copy_ppkey(struct dpp_config_obj *conf,
|
||||
struct crypto_ec_key *ppkey)
|
||||
{
|
||||
unsigned char *der = NULL;
|
||||
int der_len;
|
||||
struct wpabuf *pp_key;
|
||||
|
||||
der_len = i2d_PUBKEY(ppkey, &der);
|
||||
if (der_len <= 0)
|
||||
pp_key = crypto_ec_key_get_subject_public_key(ppkey);
|
||||
if (!pp_key)
|
||||
return;
|
||||
|
||||
wpabuf_free(conf->pp_key);
|
||||
conf->pp_key = wpabuf_alloc_copy(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
conf->pp_key = pp_key;
|
||||
}
|
||||
|
||||
|
||||
static void dpp_copy_netaccesskey(struct dpp_authentication *auth,
|
||||
struct dpp_config_obj *conf)
|
||||
{
|
||||
unsigned char *der = NULL;
|
||||
int der_len;
|
||||
EC_KEY *eckey;
|
||||
EVP_PKEY *own_key;
|
||||
struct wpabuf *net_access_key;
|
||||
struct crypto_ec_key *own_key;
|
||||
|
||||
own_key = auth->own_protocol_key;
|
||||
#ifdef CONFIG_DPP2
|
||||
@ -2457,19 +2433,13 @@ static void dpp_copy_netaccesskey(struct dpp_authentication *auth,
|
||||
auth->reconfig_old_protocol_key)
|
||||
own_key = auth->reconfig_old_protocol_key;
|
||||
#endif /* CONFIG_DPP2 */
|
||||
eckey = EVP_PKEY_get1_EC_KEY(own_key);
|
||||
if (!eckey)
|
||||
|
||||
net_access_key = crypto_ec_key_get_ecprivate_key(own_key, true);
|
||||
if (!net_access_key)
|
||||
return;
|
||||
|
||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
||||
if (der_len <= 0) {
|
||||
EC_KEY_free(eckey);
|
||||
return;
|
||||
}
|
||||
wpabuf_free(auth->net_access_key);
|
||||
auth->net_access_key = wpabuf_alloc_copy(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
EC_KEY_free(eckey);
|
||||
auth->net_access_key = net_access_key;
|
||||
}
|
||||
|
||||
|
||||
@ -2480,7 +2450,7 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth,
|
||||
struct dpp_signed_connector_info info;
|
||||
struct json_token *token, *csign, *ppkey;
|
||||
int ret = -1;
|
||||
EVP_PKEY *csign_pub = NULL, *pp_pub = NULL;
|
||||
struct crypto_ec_key *csign_pub = NULL, *pp_pub = NULL;
|
||||
const struct dpp_curve_params *key_curve = NULL, *pp_curve = NULL;
|
||||
const char *signed_connector;
|
||||
|
||||
@ -2560,8 +2530,8 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth,
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
EVP_PKEY_free(csign_pub);
|
||||
EVP_PKEY_free(pp_pub);
|
||||
crypto_ec_key_deinit(csign_pub);
|
||||
crypto_ec_key_deinit(pp_pub);
|
||||
os_free(info.payload);
|
||||
return ret;
|
||||
}
|
||||
@ -2586,7 +2556,7 @@ static int dpp_parse_cred_dot1x(struct dpp_authentication *auth,
|
||||
return -1;
|
||||
}
|
||||
wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Received certBag", conf->certbag);
|
||||
conf->certs = dpp_pkcs7_certs(conf->certbag);
|
||||
conf->certs = crypto_pkcs7_get_certificates(conf->certbag);
|
||||
if (!conf->certs) {
|
||||
dpp_auth_fail(auth, "No certificates in certBag");
|
||||
return -1;
|
||||
@ -3394,11 +3364,11 @@ void dpp_configurator_free(struct dpp_configurator *conf)
|
||||
{
|
||||
if (!conf)
|
||||
return;
|
||||
EVP_PKEY_free(conf->csign);
|
||||
crypto_ec_key_deinit(conf->csign);
|
||||
os_free(conf->kid);
|
||||
os_free(conf->connector);
|
||||
EVP_PKEY_free(conf->connector_key);
|
||||
EVP_PKEY_free(conf->pp_key);
|
||||
crypto_ec_key_deinit(conf->connector_key);
|
||||
crypto_ec_key_deinit(conf->pp_key);
|
||||
os_free(conf);
|
||||
}
|
||||
|
||||
@ -3406,23 +3376,19 @@ void dpp_configurator_free(struct dpp_configurator *conf)
|
||||
int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
EC_KEY *eckey;
|
||||
int key_len, ret = -1;
|
||||
unsigned char *key = NULL;
|
||||
struct wpabuf *key;
|
||||
int ret = -1;
|
||||
|
||||
if (!conf->csign)
|
||||
return -1;
|
||||
|
||||
eckey = EVP_PKEY_get1_EC_KEY(conf->csign);
|
||||
if (!eckey)
|
||||
key = crypto_ec_key_get_ecprivate_key(conf->csign, true);
|
||||
if (!key)
|
||||
return -1;
|
||||
|
||||
key_len = i2d_ECPrivateKey(eckey, &key);
|
||||
if (key_len > 0)
|
||||
ret = wpa_snprintf_hex(buf, buflen, key, key_len);
|
||||
ret = wpa_snprintf_hex(buf, buflen, wpabuf_head(key), wpabuf_len(key));
|
||||
|
||||
EC_KEY_free(eckey);
|
||||
OPENSSL_free(key);
|
||||
wpabuf_clear_free(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3434,7 +3400,7 @@ static int dpp_configurator_gen_kid(struct dpp_configurator *conf)
|
||||
size_t len[1];
|
||||
int res;
|
||||
|
||||
csign_pub = dpp_get_pubkey_point(conf->csign, 1);
|
||||
csign_pub = crypto_ec_key_get_pubkey_point(conf->csign, 1);
|
||||
if (!csign_pub) {
|
||||
wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
|
||||
return -1;
|
||||
@ -3670,7 +3636,7 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
|
||||
struct json_token *root = NULL, *netkey, *token;
|
||||
struct json_token *own_root = NULL;
|
||||
enum dpp_status_error ret = 255, res;
|
||||
EVP_PKEY *own_key = NULL, *peer_key = NULL;
|
||||
struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
|
||||
struct wpabuf *own_key_pub = NULL;
|
||||
const struct dpp_curve_params *curve, *own_curve;
|
||||
struct dpp_signed_connector_info info;
|
||||
@ -3776,9 +3742,9 @@ dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
|
||||
os_memset(intro, 0, sizeof(*intro));
|
||||
os_memset(Nx, 0, sizeof(Nx));
|
||||
os_free(info.payload);
|
||||
EVP_PKEY_free(own_key);
|
||||
crypto_ec_key_deinit(own_key);
|
||||
wpabuf_free(own_key_pub);
|
||||
EVP_PKEY_free(peer_key);
|
||||
crypto_ec_key_deinit(peer_key);
|
||||
json_free(root);
|
||||
json_free(own_root);
|
||||
return ret;
|
||||
@ -4129,7 +4095,7 @@ static int dpp_nfc_update_bi_key(struct dpp_bootstrap_info *own_bi,
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Update own bootstrapping key to match peer curve from NFC handover");
|
||||
|
||||
EVP_PKEY_free(own_bi->pubkey);
|
||||
crypto_ec_key_deinit(own_bi->pubkey);
|
||||
own_bi->pubkey = NULL;
|
||||
|
||||
if (dpp_keygen(own_bi, peer_bi->curve->name, NULL, 0) < 0 ||
|
||||
@ -4275,33 +4241,24 @@ int dpp_configurator_from_backup(struct dpp_global *dpp,
|
||||
struct dpp_asymmetric_key *key)
|
||||
{
|
||||
struct dpp_configurator *conf;
|
||||
const EC_KEY *eckey, *eckey_pp;
|
||||
const EC_GROUP *group, *group_pp;
|
||||
int nid;
|
||||
const struct dpp_curve_params *curve;
|
||||
const struct dpp_curve_params *curve, *curve_pp;
|
||||
|
||||
if (!key->csign || !key->pp_key)
|
||||
return -1;
|
||||
eckey = EVP_PKEY_get0_EC_KEY(key->csign);
|
||||
if (!eckey)
|
||||
return -1;
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
if (!group)
|
||||
return -1;
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
curve = dpp_get_curve_nid(nid);
|
||||
|
||||
curve = dpp_get_curve_ike_group(crypto_ec_key_group(key->csign));
|
||||
if (!curve) {
|
||||
wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key");
|
||||
return -1;
|
||||
}
|
||||
eckey_pp = EVP_PKEY_get0_EC_KEY(key->pp_key);
|
||||
if (!eckey_pp)
|
||||
|
||||
curve_pp = dpp_get_curve_ike_group(crypto_ec_key_group(key->pp_key));
|
||||
if (!curve_pp) {
|
||||
wpa_printf(MSG_INFO, "DPP: Unsupported group in ppKey");
|
||||
return -1;
|
||||
group_pp = EC_KEY_get0_group(eckey_pp);
|
||||
if (!group_pp)
|
||||
return -1;
|
||||
if (EC_GROUP_get_curve_name(group) !=
|
||||
EC_GROUP_get_curve_name(group_pp)) {
|
||||
}
|
||||
|
||||
if (curve != curve_pp) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"DPP: Mismatch in c-sign-key and ppKey groups");
|
||||
return -1;
|
||||
|
@ -11,13 +11,11 @@
|
||||
#define DPP_H
|
||||
|
||||
#ifdef CONFIG_DPP
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "utils/list.h"
|
||||
#include "common/wpa_common.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
struct crypto_ecdh;
|
||||
struct hostapd_ip_addr;
|
||||
struct dpp_global;
|
||||
struct json_token;
|
||||
@ -157,7 +155,7 @@ struct dpp_bootstrap_info {
|
||||
bool channels_listed;
|
||||
u8 version;
|
||||
int own;
|
||||
EVP_PKEY *pubkey;
|
||||
struct crypto_ec_key *pubkey;
|
||||
u8 pubkey_hash[SHA256_MAC_LEN];
|
||||
u8 pubkey_hash_chirp[SHA256_MAC_LEN];
|
||||
const struct dpp_curve_params *curve;
|
||||
@ -180,12 +178,12 @@ struct dpp_pkex {
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
char *identifier;
|
||||
char *code;
|
||||
EVP_PKEY *x;
|
||||
EVP_PKEY *y;
|
||||
struct crypto_ec_key *x;
|
||||
struct crypto_ec_key *y;
|
||||
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
||||
u8 Nx[DPP_MAX_SHARED_SECRET_LEN];
|
||||
u8 z[DPP_MAX_HASH_LEN];
|
||||
EVP_PKEY *peer_bootstrap_key;
|
||||
struct crypto_ec_key *peer_bootstrap_key;
|
||||
struct wpabuf *exchange_req;
|
||||
struct wpabuf *exchange_resp;
|
||||
unsigned int t; /* number of failures on code use */
|
||||
@ -234,8 +232,8 @@ struct dpp_configuration {
|
||||
|
||||
struct dpp_asymmetric_key {
|
||||
struct dpp_asymmetric_key *next;
|
||||
EVP_PKEY *csign;
|
||||
EVP_PKEY *pp_key;
|
||||
struct crypto_ec_key *csign;
|
||||
struct crypto_ec_key *pp_key;
|
||||
char *config_template;
|
||||
char *connector_template;
|
||||
};
|
||||
@ -266,9 +264,9 @@ struct dpp_authentication {
|
||||
u8 i_capab;
|
||||
u8 r_capab;
|
||||
enum dpp_netrole e_netrole;
|
||||
EVP_PKEY *own_protocol_key;
|
||||
EVP_PKEY *peer_protocol_key;
|
||||
EVP_PKEY *reconfig_old_protocol_key;
|
||||
struct crypto_ec_key *own_protocol_key;
|
||||
struct crypto_ec_key *peer_protocol_key;
|
||||
struct crypto_ec_key *reconfig_old_protocol_key;
|
||||
struct wpabuf *req_msg;
|
||||
struct wpabuf *resp_msg;
|
||||
struct wpabuf *reconfig_req_msg;
|
||||
@ -361,13 +359,13 @@ struct dpp_configurator {
|
||||
struct dl_list list;
|
||||
unsigned int id;
|
||||
int own;
|
||||
EVP_PKEY *csign;
|
||||
struct crypto_ec_key *csign;
|
||||
u8 kid_hash[SHA256_MAC_LEN];
|
||||
char *kid;
|
||||
const struct dpp_curve_params *curve;
|
||||
char *connector; /* own Connector for reconfiguration */
|
||||
EVP_PKEY *connector_key;
|
||||
EVP_PKEY *pp_key;
|
||||
struct crypto_ec_key *connector_key;
|
||||
struct crypto_ec_key *pp_key;
|
||||
};
|
||||
|
||||
struct dpp_introduction {
|
||||
@ -633,7 +631,6 @@ void dpp_pfs_free(struct dpp_pfs *pfs);
|
||||
|
||||
struct wpabuf * dpp_build_csr(struct dpp_authentication *auth,
|
||||
const char *name);
|
||||
struct wpabuf * dpp_pkcs7_certs(const struct wpabuf *pkcs7);
|
||||
int dpp_validate_csr(struct dpp_authentication *auth, const struct wpabuf *csr);
|
||||
|
||||
struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp,
|
||||
@ -676,6 +673,7 @@ int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data,
|
||||
int dpp_controller_start(struct dpp_global *dpp,
|
||||
struct dpp_controller_config *config);
|
||||
void dpp_controller_stop(struct dpp_global *dpp);
|
||||
void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx);
|
||||
struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
|
||||
unsigned int id);
|
||||
void dpp_controller_new_qr_code(struct dpp_global *dpp,
|
||||
|
@ -456,7 +456,7 @@ static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len);
|
||||
|
||||
EVP_PKEY_free(auth->own_protocol_key);
|
||||
crypto_ec_key_deinit(auth->own_protocol_key);
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (dpp_protocol_key_override_len) {
|
||||
const struct dpp_curve_params *tmp_curve;
|
||||
@ -475,7 +475,7 @@ static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
|
||||
if (!auth->own_protocol_key)
|
||||
goto fail;
|
||||
|
||||
pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
if (!pr)
|
||||
goto fail;
|
||||
|
||||
@ -671,8 +671,7 @@ dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
|
||||
unsigned int freq, const u8 *hdr, const u8 *attr_start,
|
||||
size_t attr_len)
|
||||
{
|
||||
EVP_PKEY *pi = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
struct crypto_ec_key *pi = NULL;
|
||||
size_t secret_len;
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
@ -928,8 +927,7 @@ dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
|
||||
return auth;
|
||||
fail:
|
||||
bin_clear_free(unwrapped, unwrapped_len);
|
||||
EVP_PKEY_free(pi);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
crypto_ec_key_deinit(pi);
|
||||
dpp_auth_deinit(auth);
|
||||
return NULL;
|
||||
}
|
||||
@ -1235,7 +1233,7 @@ struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
|
||||
if (!auth->own_protocol_key)
|
||||
goto fail;
|
||||
|
||||
pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
pi = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
if (!pi)
|
||||
goto fail;
|
||||
|
||||
@ -1405,7 +1403,7 @@ struct wpabuf *
|
||||
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len)
|
||||
{
|
||||
EVP_PKEY *pr;
|
||||
struct crypto_ec_key *pr;
|
||||
size_t secret_len;
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
@ -1567,7 +1565,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
|
||||
goto fail;
|
||||
}
|
||||
EVP_PKEY_free(auth->peer_protocol_key);
|
||||
crypto_ec_key_deinit(auth->peer_protocol_key);
|
||||
auth->peer_protocol_key = pr;
|
||||
pr = NULL;
|
||||
|
||||
@ -1737,7 +1735,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||
fail:
|
||||
bin_clear_free(unwrapped, unwrapped_len);
|
||||
bin_clear_free(unwrapped2, unwrapped2_len);
|
||||
EVP_PKEY_free(pr);
|
||||
crypto_ec_key_deinit(pr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "crypto/aes.h"
|
||||
@ -19,28 +17,13 @@
|
||||
|
||||
#ifdef CONFIG_DPP2
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
/* Compatibility wrappers for older versions. */
|
||||
|
||||
static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_EC)
|
||||
return NULL;
|
||||
return pkey->pkey.ec;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
|
||||
{
|
||||
while (key) {
|
||||
struct dpp_asymmetric_key *next = key->next;
|
||||
|
||||
EVP_PKEY_free(key->csign);
|
||||
EVP_PKEY_free(key->pp_key);
|
||||
crypto_ec_key_deinit(key->csign);
|
||||
crypto_ec_key_deinit(key->pp_key);
|
||||
str_clear_free(key->config_template);
|
||||
str_clear_free(key->connector_template);
|
||||
os_free(key);
|
||||
@ -56,23 +39,13 @@ static struct wpabuf * dpp_build_conf_params(struct dpp_configurator *conf)
|
||||
/* TODO: proper template values */
|
||||
const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}";
|
||||
const char *connector_template = NULL;
|
||||
EC_KEY *eckey;
|
||||
unsigned char *der = NULL;
|
||||
int der_len;
|
||||
|
||||
if (!conf->pp_key)
|
||||
return NULL;
|
||||
eckey = EVP_PKEY_get0_EC_KEY(conf->pp_key);
|
||||
if (!eckey)
|
||||
return NULL;
|
||||
|
||||
EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
|
||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
||||
if (der_len > 0)
|
||||
priv_key = wpabuf_alloc_copy(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
priv_key = crypto_ec_key_get_ecprivate_key(conf->pp_key, false);
|
||||
if (!priv_key)
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
len = 100 + os_strlen(conf_template);
|
||||
if (connector_template)
|
||||
@ -178,20 +151,11 @@ static struct wpabuf * dpp_build_key_alg(const struct dpp_curve_params *curve)
|
||||
static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth)
|
||||
{
|
||||
struct wpabuf *key = NULL, *attr, *alg, *priv_key = NULL;
|
||||
EC_KEY *eckey;
|
||||
unsigned char *der = NULL;
|
||||
int der_len;
|
||||
|
||||
eckey = EVP_PKEY_get0_EC_KEY(auth->conf->csign);
|
||||
if (!eckey)
|
||||
priv_key = crypto_ec_key_get_ecprivate_key(auth->conf->csign, false);
|
||||
if (!priv_key)
|
||||
return NULL;
|
||||
|
||||
EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
|
||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
||||
if (der_len > 0)
|
||||
priv_key = wpabuf_alloc_copy(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
|
||||
alg = dpp_build_key_alg(auth->conf->curve);
|
||||
|
||||
/* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */
|
||||
@ -900,7 +864,6 @@ dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
|
||||
struct asn1_oid oid;
|
||||
char txt[80];
|
||||
struct dpp_asymmetric_key *key;
|
||||
EC_KEY *eckey;
|
||||
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "DPP: OneAsymmetricKey", buf, len);
|
||||
|
||||
@ -975,18 +938,9 @@ dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "DPP: PrivateKey",
|
||||
hdr.payload, hdr.length);
|
||||
pos = hdr.payload + hdr.length;
|
||||
eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
|
||||
if (!eckey) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
key->csign = crypto_ec_key_parse_priv(hdr.payload, hdr.length);
|
||||
if (!key->csign)
|
||||
goto fail;
|
||||
}
|
||||
key->csign = EVP_PKEY_new();
|
||||
if (!key->csign || EVP_PKEY_assign_EC_KEY(key->csign, eckey) != 1) {
|
||||
EC_KEY_free(eckey);
|
||||
goto fail;
|
||||
}
|
||||
if (wpa_debug_show_keys)
|
||||
dpp_debug_print_key("DPP: Received c-sign-key", key->csign);
|
||||
|
||||
@ -1096,18 +1050,9 @@ dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "DPP: privacyProtectionKey",
|
||||
hdr.payload, hdr.length);
|
||||
pos = hdr.payload + hdr.length;
|
||||
eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
|
||||
if (!eckey) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
key->pp_key = crypto_ec_key_parse_priv(hdr.payload, hdr.length);
|
||||
if (!key->pp_key)
|
||||
goto fail;
|
||||
}
|
||||
key->pp_key = EVP_PKEY_new();
|
||||
if (!key->pp_key || EVP_PKEY_assign_EC_KEY(key->pp_key, eckey) != 1) {
|
||||
EC_KEY_free(eckey);
|
||||
goto fail;
|
||||
}
|
||||
if (wpa_debug_show_keys)
|
||||
dpp_debug_print_key("DPP: Received privacyProtectionKey",
|
||||
key->pp_key);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,10 +37,11 @@ struct wpabuf * dpp_build_conn_status(enum dpp_status_error result,
|
||||
struct json_token * dpp_parse_own_connector(const char *own_connector);
|
||||
int dpp_connector_match_groups(struct json_token *own_root,
|
||||
struct json_token *peer_root, bool reconfig);
|
||||
int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
|
||||
const char *kid, const struct dpp_curve_params *curve);
|
||||
EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve);
|
||||
int dpp_build_jwk(struct wpabuf *buf, const char *name,
|
||||
struct crypto_ec_key *key, const char *kid,
|
||||
const struct dpp_curve_params *curve);
|
||||
struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve);
|
||||
int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
||||
unsigned int neg_freq,
|
||||
struct hostapd_hw_modes *own_modes, u16 num_modes);
|
||||
@ -65,32 +66,27 @@ struct dpp_signed_connector_info {
|
||||
|
||||
enum dpp_status_error
|
||||
dpp_process_signed_connector(struct dpp_signed_connector_info *info,
|
||||
EVP_PKEY *csign_pub, const char *connector);
|
||||
struct crypto_ec_key *csign_pub,
|
||||
const char *connector);
|
||||
enum dpp_status_error
|
||||
dpp_check_signed_connector(struct dpp_signed_connector_info *info,
|
||||
const u8 *csign_key, size_t csign_key_len,
|
||||
const u8 *peer_connector, size_t peer_connector_len);
|
||||
const struct dpp_curve_params * dpp_get_curve_name(const char *name);
|
||||
const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name);
|
||||
const struct dpp_curve_params * dpp_get_curve_nid(int nid);
|
||||
const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group);
|
||||
int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
|
||||
const u8 *data, size_t data_len);
|
||||
struct wpabuf * dpp_get_pubkey_point(EVP_PKEY *pkey, int prefix);
|
||||
EVP_PKEY * dpp_set_pubkey_point_group(const EC_GROUP *group,
|
||||
const u8 *buf_x, const u8 *buf_y,
|
||||
size_t len);
|
||||
EVP_PKEY * dpp_set_pubkey_point(EVP_PKEY *group_key, const u8 *buf, size_t len);
|
||||
int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len);
|
||||
struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
|
||||
const u8 *buf, size_t len);
|
||||
int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len,
|
||||
const char *label, u8 *out, size_t outlen);
|
||||
int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len,
|
||||
size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac);
|
||||
int dpp_ecdh(EVP_PKEY *own, EVP_PKEY *peer, u8 *secret, size_t *secret_len);
|
||||
void dpp_debug_print_point(const char *title, const EC_GROUP *group,
|
||||
const EC_POINT *point);
|
||||
void dpp_debug_print_key(const char *title, EVP_PKEY *key);
|
||||
int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer,
|
||||
u8 *secret, size_t *secret_len);
|
||||
void dpp_debug_print_key(const char *title, struct crypto_ec_key *key);
|
||||
int dpp_pbkdf2(size_t hash_len, const u8 *password, size_t password_len,
|
||||
const u8 *salt, size_t salt_len, unsigned int iterations,
|
||||
u8 *buf, size_t buflen);
|
||||
@ -99,9 +95,9 @@ int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi,
|
||||
int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi);
|
||||
int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
|
||||
const u8 *privkey, size_t privkey_len);
|
||||
EVP_PKEY * dpp_set_keypair(const struct dpp_curve_params **curve,
|
||||
const u8 *privkey, size_t privkey_len);
|
||||
EVP_PKEY * dpp_gen_keypair(const struct dpp_curve_params *curve);
|
||||
struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve,
|
||||
const u8 *privkey, size_t privkey_len);
|
||||
struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve);
|
||||
int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, unsigned int hash_len);
|
||||
int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, unsigned int hash_len);
|
||||
int dpp_derive_bk_ke(struct dpp_authentication *auth);
|
||||
@ -111,15 +107,16 @@ int dpp_auth_derive_l_responder(struct dpp_authentication *auth);
|
||||
int dpp_auth_derive_l_initiator(struct dpp_authentication *auth);
|
||||
int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len);
|
||||
int dpp_derive_pmkid(const struct dpp_curve_params *curve,
|
||||
EVP_PKEY *own_key, EVP_PKEY *peer_key, u8 *pmkid);
|
||||
EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
|
||||
const u8 *mac_init, const char *code,
|
||||
const char *identifier, BN_CTX *bnctx,
|
||||
EC_GROUP **ret_group);
|
||||
EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
|
||||
const u8 *mac_resp, const char *code,
|
||||
const char *identifier, BN_CTX *bnctx,
|
||||
EC_GROUP **ret_group);
|
||||
struct crypto_ec_key *own_key,
|
||||
struct crypto_ec_key *peer_key, u8 *pmkid);
|
||||
struct crypto_ec_point *
|
||||
dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
|
||||
const char *code, const char *identifier,
|
||||
struct crypto_ec **ret_ec);
|
||||
struct crypto_ec_point *
|
||||
dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
|
||||
const char *code, const char *identifier,
|
||||
struct crypto_ec **ret_ec);
|
||||
int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
|
||||
const u8 *Mx, size_t Mx_len,
|
||||
const u8 *Nx, size_t Nx_len,
|
||||
@ -133,20 +130,21 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||
int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
|
||||
const u8 *r_proto, u16 r_proto_len,
|
||||
struct json_token *net_access_key);
|
||||
EC_POINT * dpp_decrypt_e_id(EVP_PKEY *ppkey, EVP_PKEY *a_nonce,
|
||||
EVP_PKEY *e_prime_id);
|
||||
struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
|
||||
struct crypto_ec_key *a_nonce,
|
||||
struct crypto_ec_key *e_prime_id);
|
||||
char * dpp_sign_connector(struct dpp_configurator *conf,
|
||||
const struct wpabuf *dppcon);
|
||||
int dpp_test_gen_invalid_key(struct wpabuf *msg,
|
||||
const struct dpp_curve_params *curve);
|
||||
|
||||
struct dpp_reconfig_id {
|
||||
const EC_GROUP *group;
|
||||
EC_POINT *e_id; /* E-id */
|
||||
EVP_PKEY *csign;
|
||||
EVP_PKEY *a_nonce; /* A-NONCE */
|
||||
EVP_PKEY *e_prime_id; /* E'-id */
|
||||
EVP_PKEY *pp_key;
|
||||
struct crypto_ec *ec;
|
||||
struct crypto_ec_point *e_id; /* E-id */
|
||||
struct crypto_ec_key *csign;
|
||||
struct crypto_ec_key *a_nonce; /* A-NONCE */
|
||||
struct crypto_ec_key *e_prime_id; /* E'-id */
|
||||
struct crypto_ec_key *pp_key;
|
||||
};
|
||||
|
||||
/* dpp_tcp.c */
|
||||
|
@ -8,8 +8,6 @@
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
@ -27,30 +25,13 @@ u8 dpp_pkex_ephemeral_key_override[600];
|
||||
size_t dpp_pkex_ephemeral_key_override_len = 0;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
/* Compatibility wrappers for older versions. */
|
||||
|
||||
static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_EC)
|
||||
return NULL;
|
||||
return pkey->pkey.ec;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
|
||||
{
|
||||
const EC_KEY *X_ec;
|
||||
const EC_POINT *X_point;
|
||||
BN_CTX *bnctx = NULL;
|
||||
EC_GROUP *group = NULL;
|
||||
EC_POINT *Qi = NULL, *M = NULL;
|
||||
struct wpabuf *M_buf = NULL;
|
||||
BIGNUM *Mx = NULL, *My = NULL;
|
||||
struct crypto_ec *ec = NULL;
|
||||
const struct crypto_ec_point *X;
|
||||
struct crypto_ec_point *Qi = NULL, *M = NULL;
|
||||
u8 *Mx, *My;
|
||||
struct wpabuf *msg = NULL;
|
||||
size_t attr_len;
|
||||
const struct dpp_curve_params *curve = pkex->own_bi->curve;
|
||||
@ -58,11 +39,8 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
|
||||
wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
|
||||
|
||||
/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
|
||||
bnctx = BN_CTX_new();
|
||||
if (!bnctx)
|
||||
goto fail;
|
||||
Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
|
||||
pkex->identifier, bnctx, &group);
|
||||
pkex->identifier, &ec);
|
||||
if (!Qi)
|
||||
goto fail;
|
||||
|
||||
@ -86,21 +64,15 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
|
||||
goto fail;
|
||||
|
||||
/* M = X + Qi */
|
||||
X_ec = EVP_PKEY_get0_EC_KEY(pkex->x);
|
||||
if (!X_ec)
|
||||
X = crypto_ec_key_get_public_key(pkex->x);
|
||||
M = crypto_ec_point_init(ec);
|
||||
if (!X || !M)
|
||||
goto fail;
|
||||
X_point = EC_KEY_get0_public_key(X_ec);
|
||||
if (!X_point)
|
||||
crypto_ec_point_debug_print(ec, X, "DPP: X");
|
||||
|
||||
if (crypto_ec_point_add(ec, X, Qi, M))
|
||||
goto fail;
|
||||
dpp_debug_print_point("DPP: X", group, X_point);
|
||||
M = EC_POINT_new(group);
|
||||
Mx = BN_new();
|
||||
My = BN_new();
|
||||
if (!M || !Mx || !My ||
|
||||
EC_POINT_add(group, M, X_point, Qi, bnctx) != 1 ||
|
||||
EC_POINT_get_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1)
|
||||
goto fail;
|
||||
dpp_debug_print_point("DPP: M", group, M);
|
||||
crypto_ec_point_debug_print(ec, M, "DPP: M");
|
||||
|
||||
/* Initiator -> Responder: group, [identifier,] M */
|
||||
attr_len = 4 + 2;
|
||||
@ -154,21 +126,17 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
|
||||
}
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
if (dpp_bn2bin_pad(Mx, wpabuf_put(msg, curve->prime_len),
|
||||
curve->prime_len) < 0 ||
|
||||
dpp_bn2bin_pad(Mx, pkex->Mx, curve->prime_len) < 0 ||
|
||||
dpp_bn2bin_pad(My, wpabuf_put(msg, curve->prime_len),
|
||||
curve->prime_len) < 0)
|
||||
Mx = wpabuf_put(msg, curve->prime_len);
|
||||
My = wpabuf_put(msg, curve->prime_len);
|
||||
if (crypto_ec_point_to_bin(ec, M, Mx, My))
|
||||
goto fail;
|
||||
|
||||
os_memcpy(pkex->Mx, Mx, curve->prime_len);
|
||||
|
||||
out:
|
||||
wpabuf_free(M_buf);
|
||||
EC_POINT_free(M);
|
||||
EC_POINT_free(Qi);
|
||||
BN_clear_free(Mx);
|
||||
BN_clear_free(My);
|
||||
BN_CTX_free(bnctx);
|
||||
EC_GROUP_free(group);
|
||||
crypto_ec_point_deinit(M, 1);
|
||||
crypto_ec_point_deinit(Qi, 1);
|
||||
crypto_ec_deinit(ec);
|
||||
return msg;
|
||||
fail:
|
||||
wpa_printf(MSG_INFO, "DPP: Failed to build PKEX Exchange Request");
|
||||
@ -227,7 +195,7 @@ struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
|
||||
static struct wpabuf *
|
||||
dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
|
||||
enum dpp_status_error status,
|
||||
const BIGNUM *Nx, const BIGNUM *Ny)
|
||||
const u8 *Nx, const u8 *Ny)
|
||||
{
|
||||
struct wpabuf *msg = NULL;
|
||||
size_t attr_len;
|
||||
@ -291,12 +259,9 @@ dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
|
||||
}
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
if (dpp_bn2bin_pad(Nx, wpabuf_put(msg, curve->prime_len),
|
||||
curve->prime_len) < 0 ||
|
||||
dpp_bn2bin_pad(Nx, pkex->Nx, curve->prime_len) < 0 ||
|
||||
dpp_bn2bin_pad(Ny, wpabuf_put(msg, curve->prime_len),
|
||||
curve->prime_len) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(msg, Nx, curve->prime_len);
|
||||
wpabuf_put_data(msg, Ny, curve->prime_len);
|
||||
os_memcpy(pkex->Nx, Nx, curve->prime_len);
|
||||
|
||||
skip_encrypted_key:
|
||||
if (status == DPP_STATUS_BAD_GROUP) {
|
||||
@ -352,14 +317,11 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
|
||||
const struct dpp_curve_params *curve = bi->curve;
|
||||
u16 ike_group;
|
||||
struct dpp_pkex *pkex = NULL;
|
||||
EC_POINT *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
|
||||
BN_CTX *bnctx = NULL;
|
||||
EC_GROUP *group = NULL;
|
||||
BIGNUM *Mx = NULL, *My = NULL;
|
||||
const EC_KEY *Y_ec;
|
||||
EC_KEY *X_ec = NULL;
|
||||
const EC_POINT *Y_point;
|
||||
BIGNUM *Nx = NULL, *Ny = NULL;
|
||||
struct crypto_ec_point *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL,
|
||||
*N = NULL;
|
||||
struct crypto_ec *ec = NULL;
|
||||
const struct crypto_ec_point *Y;
|
||||
u8 *x_coord = NULL, *y_coord = NULL;
|
||||
u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
|
||||
size_t Kx_len;
|
||||
int res;
|
||||
@ -424,34 +386,27 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
|
||||
}
|
||||
|
||||
/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
|
||||
bnctx = BN_CTX_new();
|
||||
if (!bnctx)
|
||||
goto fail;
|
||||
Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, bnctx,
|
||||
&group);
|
||||
Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, &ec);
|
||||
if (!Qi)
|
||||
goto fail;
|
||||
|
||||
/* X' = M - Qi */
|
||||
X = EC_POINT_new(group);
|
||||
M = EC_POINT_new(group);
|
||||
Mx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
|
||||
My = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
|
||||
if (!X || !M || !Mx || !My ||
|
||||
EC_POINT_set_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1 ||
|
||||
EC_POINT_is_at_infinity(group, M) ||
|
||||
!EC_POINT_is_on_curve(group, M, bnctx) ||
|
||||
EC_POINT_invert(group, Qi, bnctx) != 1 ||
|
||||
EC_POINT_add(group, X, M, Qi, bnctx) != 1 ||
|
||||
EC_POINT_is_at_infinity(group, X) ||
|
||||
!EC_POINT_is_on_curve(group, X, bnctx)) {
|
||||
X = crypto_ec_point_init(ec);
|
||||
M = crypto_ec_point_from_bin(ec, attr_key);
|
||||
if (!X || !M ||
|
||||
crypto_ec_point_is_at_infinity(ec, M) ||
|
||||
!crypto_ec_point_is_on_curve(ec, M) ||
|
||||
crypto_ec_point_invert(ec, Qi) ||
|
||||
crypto_ec_point_add(ec, M, Qi, X) ||
|
||||
crypto_ec_point_is_at_infinity(ec, X) ||
|
||||
!crypto_ec_point_is_on_curve(ec, X)) {
|
||||
wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
|
||||
"Invalid Encrypted Key value");
|
||||
bi->pkex_t++;
|
||||
goto fail;
|
||||
}
|
||||
dpp_debug_print_point("DPP: M", group, M);
|
||||
dpp_debug_print_point("DPP: X'", group, X);
|
||||
crypto_ec_point_debug_print(ec, M, "DPP: M");
|
||||
crypto_ec_point_debug_print(ec, X, "DPP: X'");
|
||||
|
||||
pkex = os_zalloc(sizeof(*pkex));
|
||||
if (!pkex)
|
||||
@ -472,18 +427,19 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
|
||||
|
||||
os_memcpy(pkex->Mx, attr_key, attr_key_len / 2);
|
||||
|
||||
X_ec = EC_KEY_new();
|
||||
if (!X_ec ||
|
||||
EC_KEY_set_group(X_ec, group) != 1 ||
|
||||
EC_KEY_set_public_key(X_ec, X) != 1)
|
||||
x_coord = os_malloc(curve->prime_len);
|
||||
y_coord = os_malloc(curve->prime_len);
|
||||
if (!x_coord || !y_coord ||
|
||||
crypto_ec_point_to_bin(ec, X, x_coord, y_coord))
|
||||
goto fail;
|
||||
pkex->x = EVP_PKEY_new();
|
||||
if (!pkex->x ||
|
||||
EVP_PKEY_set1_EC_KEY(pkex->x, X_ec) != 1)
|
||||
|
||||
pkex->x = crypto_ec_key_set_pub(curve->ike_group, x_coord,
|
||||
y_coord, crypto_ec_prime_len(ec));
|
||||
if (!pkex->x)
|
||||
goto fail;
|
||||
|
||||
/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
|
||||
Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, bnctx, NULL);
|
||||
Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, NULL);
|
||||
if (!Qr)
|
||||
goto fail;
|
||||
|
||||
@ -507,24 +463,20 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
|
||||
goto fail;
|
||||
|
||||
/* N = Y + Qr */
|
||||
Y_ec = EVP_PKEY_get0_EC_KEY(pkex->y);
|
||||
if (!Y_ec)
|
||||
Y = crypto_ec_key_get_public_key(pkex->y);
|
||||
if (!Y)
|
||||
goto fail;
|
||||
Y_point = EC_KEY_get0_public_key(Y_ec);
|
||||
if (!Y_point)
|
||||
crypto_ec_point_debug_print(ec, Y, "DPP: Y");
|
||||
|
||||
N = crypto_ec_point_init(ec);
|
||||
if (!N ||
|
||||
crypto_ec_point_add(ec, Y, Qr, N) ||
|
||||
crypto_ec_point_to_bin(ec, N, x_coord, y_coord))
|
||||
goto fail;
|
||||
dpp_debug_print_point("DPP: Y", group, Y_point);
|
||||
N = EC_POINT_new(group);
|
||||
Nx = BN_new();
|
||||
Ny = BN_new();
|
||||
if (!N || !Nx || !Ny ||
|
||||
EC_POINT_add(group, N, Y_point, Qr, bnctx) != 1 ||
|
||||
EC_POINT_get_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1)
|
||||
goto fail;
|
||||
dpp_debug_print_point("DPP: N", group, N);
|
||||
crypto_ec_point_debug_print(ec, N, "DPP: N");
|
||||
|
||||
pkex->exchange_resp = dpp_pkex_build_exchange_resp(pkex, DPP_STATUS_OK,
|
||||
Nx, Ny);
|
||||
x_coord, y_coord);
|
||||
if (!pkex->exchange_resp)
|
||||
goto fail;
|
||||
|
||||
@ -548,18 +500,14 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
|
||||
pkex->exchange_done = 1;
|
||||
|
||||
out:
|
||||
BN_CTX_free(bnctx);
|
||||
EC_POINT_free(Qi);
|
||||
EC_POINT_free(Qr);
|
||||
BN_free(Mx);
|
||||
BN_free(My);
|
||||
BN_free(Nx);
|
||||
BN_free(Ny);
|
||||
EC_POINT_free(M);
|
||||
EC_POINT_free(N);
|
||||
EC_POINT_free(X);
|
||||
EC_KEY_free(X_ec);
|
||||
EC_GROUP_free(group);
|
||||
os_free(x_coord);
|
||||
os_free(y_coord);
|
||||
crypto_ec_point_deinit(Qi, 1);
|
||||
crypto_ec_point_deinit(Qr, 1);
|
||||
crypto_ec_point_deinit(M, 1);
|
||||
crypto_ec_point_deinit(N, 1);
|
||||
crypto_ec_point_deinit(X, 1);
|
||||
crypto_ec_deinit(ec);
|
||||
return pkex;
|
||||
fail:
|
||||
wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request processing failed");
|
||||
@ -688,13 +636,11 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
|
||||
{
|
||||
const u8 *attr_status, *attr_id, *attr_key, *attr_group;
|
||||
u16 attr_status_len, attr_id_len, attr_key_len, attr_group_len;
|
||||
EC_GROUP *group = NULL;
|
||||
BN_CTX *bnctx = NULL;
|
||||
struct crypto_ec *ec = NULL;
|
||||
struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
|
||||
const struct dpp_curve_params *curve = pkex->own_bi->curve;
|
||||
EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
|
||||
BIGNUM *Nx = NULL, *Ny = NULL;
|
||||
EC_KEY *Y_ec = NULL;
|
||||
struct crypto_ec_point *Qr = NULL, *Y = NULL, *N = NULL;
|
||||
u8 *x_coord = NULL, *y_coord = NULL;
|
||||
size_t Jx_len, Kx_len;
|
||||
u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
|
||||
const u8 *addr[4];
|
||||
@ -765,45 +711,39 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
|
||||
}
|
||||
|
||||
/* Qr = H(MAC-Responder | [identifier |] code) * Pr */
|
||||
bnctx = BN_CTX_new();
|
||||
if (!bnctx)
|
||||
goto fail;
|
||||
Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
|
||||
pkex->identifier, bnctx, &group);
|
||||
pkex->identifier, &ec);
|
||||
if (!Qr)
|
||||
goto fail;
|
||||
|
||||
/* Y' = N - Qr */
|
||||
Y = EC_POINT_new(group);
|
||||
N = EC_POINT_new(group);
|
||||
Nx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
|
||||
Ny = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
|
||||
if (!Y || !N || !Nx || !Ny ||
|
||||
EC_POINT_set_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1 ||
|
||||
EC_POINT_is_at_infinity(group, N) ||
|
||||
!EC_POINT_is_on_curve(group, N, bnctx) ||
|
||||
EC_POINT_invert(group, Qr, bnctx) != 1 ||
|
||||
EC_POINT_add(group, Y, N, Qr, bnctx) != 1 ||
|
||||
EC_POINT_is_at_infinity(group, Y) ||
|
||||
!EC_POINT_is_on_curve(group, Y, bnctx)) {
|
||||
Y = crypto_ec_point_init(ec);
|
||||
N = crypto_ec_point_from_bin(ec, attr_key);
|
||||
if (!Y || !N ||
|
||||
crypto_ec_point_is_at_infinity(ec, N) ||
|
||||
!crypto_ec_point_is_on_curve(ec, N) ||
|
||||
crypto_ec_point_invert(ec, Qr) ||
|
||||
crypto_ec_point_add(ec, N, Qr, Y) ||
|
||||
crypto_ec_point_is_at_infinity(ec, Y) ||
|
||||
!crypto_ec_point_is_on_curve(ec, Y)) {
|
||||
dpp_pkex_fail(pkex, "Invalid Encrypted Key value");
|
||||
pkex->t++;
|
||||
goto fail;
|
||||
}
|
||||
dpp_debug_print_point("DPP: N", group, N);
|
||||
dpp_debug_print_point("DPP: Y'", group, Y);
|
||||
crypto_ec_point_debug_print(ec, N, "DPP: N");
|
||||
crypto_ec_point_debug_print(ec, Y, "DPP: Y'");
|
||||
|
||||
pkex->exchange_done = 1;
|
||||
|
||||
/* ECDH: J = a * Y' */
|
||||
Y_ec = EC_KEY_new();
|
||||
if (!Y_ec ||
|
||||
EC_KEY_set_group(Y_ec, group) != 1 ||
|
||||
EC_KEY_set_public_key(Y_ec, Y) != 1)
|
||||
x_coord = os_malloc(curve->prime_len);
|
||||
y_coord = os_malloc(curve->prime_len);
|
||||
if (!x_coord || !y_coord ||
|
||||
crypto_ec_point_to_bin(ec, Y, x_coord, y_coord))
|
||||
goto fail;
|
||||
pkex->y = EVP_PKEY_new();
|
||||
if (!pkex->y ||
|
||||
EVP_PKEY_set1_EC_KEY(pkex->y, Y_ec) != 1)
|
||||
pkex->y = crypto_ec_key_set_pub(curve->ike_group, x_coord, y_coord,
|
||||
curve->prime_len);
|
||||
if (!pkex->y)
|
||||
goto fail;
|
||||
if (dpp_ecdh(pkex->own_bi->pubkey, pkex->y, Jx, &Jx_len) < 0)
|
||||
goto fail;
|
||||
@ -812,9 +752,9 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
|
||||
Jx, Jx_len);
|
||||
|
||||
/* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x) */
|
||||
A_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
|
||||
Y_pub = dpp_get_pubkey_point(pkex->y, 0);
|
||||
X_pub = dpp_get_pubkey_point(pkex->x, 0);
|
||||
A_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
|
||||
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
|
||||
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
|
||||
if (!A_pub || !Y_pub || !X_pub)
|
||||
goto fail;
|
||||
addr[0] = pkex->own_mac;
|
||||
@ -855,14 +795,12 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
|
||||
wpabuf_free(A_pub);
|
||||
wpabuf_free(X_pub);
|
||||
wpabuf_free(Y_pub);
|
||||
EC_POINT_free(Qr);
|
||||
EC_POINT_free(Y);
|
||||
EC_POINT_free(N);
|
||||
BN_free(Nx);
|
||||
BN_free(Ny);
|
||||
EC_KEY_free(Y_ec);
|
||||
BN_CTX_free(bnctx);
|
||||
EC_GROUP_free(group);
|
||||
os_free(x_coord);
|
||||
os_free(y_coord);
|
||||
crypto_ec_point_deinit(Qr, 1);
|
||||
crypto_ec_point_deinit(Y, 1);
|
||||
crypto_ec_point_deinit(N, 1);
|
||||
crypto_ec_deinit(ec);
|
||||
return msg;
|
||||
fail:
|
||||
wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");
|
||||
@ -1078,9 +1016,9 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
|
||||
Jx, Jx_len);
|
||||
|
||||
/* u' = HMAC(J'.x, MAC-Initiator | A'.x | Y.x | X'.x) */
|
||||
A_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
|
||||
Y_pub = dpp_get_pubkey_point(pkex->y, 0);
|
||||
X_pub = dpp_get_pubkey_point(pkex->x, 0);
|
||||
A_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
|
||||
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
|
||||
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
|
||||
if (!A_pub || !Y_pub || !X_pub)
|
||||
goto fail;
|
||||
addr[0] = pkex->peer_mac;
|
||||
@ -1115,7 +1053,7 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
|
||||
Lx, Lx_len);
|
||||
|
||||
/* v = HMAC(L.x, MAC-Responder | B.x | X'.x | Y.x) */
|
||||
B_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
|
||||
B_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
|
||||
if (!B_pub)
|
||||
goto fail;
|
||||
addr[0] = pkex->own_mac;
|
||||
@ -1240,9 +1178,9 @@ int dpp_pkex_rx_commit_reveal_resp(struct dpp_pkex *pkex, const u8 *hdr,
|
||||
Lx, Lx_len);
|
||||
|
||||
/* v' = HMAC(L.x, MAC-Responder | B'.x | X.x | Y'.x) */
|
||||
B_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
|
||||
X_pub = dpp_get_pubkey_point(pkex->x, 0);
|
||||
Y_pub = dpp_get_pubkey_point(pkex->y, 0);
|
||||
B_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
|
||||
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
|
||||
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
|
||||
if (!B_pub || !X_pub || !Y_pub)
|
||||
goto fail;
|
||||
addr[0] = pkex->peer_mac;
|
||||
@ -1315,9 +1253,9 @@ void dpp_pkex_free(struct dpp_pkex *pkex)
|
||||
|
||||
os_free(pkex->identifier);
|
||||
os_free(pkex->code);
|
||||
EVP_PKEY_free(pkex->x);
|
||||
EVP_PKEY_free(pkex->y);
|
||||
EVP_PKEY_free(pkex->peer_bootstrap_key);
|
||||
crypto_ec_key_deinit(pkex->x);
|
||||
crypto_ec_key_deinit(pkex->y);
|
||||
crypto_ec_key_deinit(pkex->peer_bootstrap_key);
|
||||
wpabuf_free(pkex->exchange_req);
|
||||
wpabuf_free(pkex->exchange_resp);
|
||||
os_free(pkex);
|
||||
|
@ -7,8 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/json.h"
|
||||
@ -40,8 +38,7 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||
struct dpp_reconfig_id *id)
|
||||
{
|
||||
struct wpabuf *msg = NULL;
|
||||
EVP_PKEY *csign = NULL;
|
||||
const unsigned char *p;
|
||||
struct crypto_ec_key *csign = NULL;
|
||||
struct wpabuf *uncomp;
|
||||
u8 hash[SHA256_MAC_LEN];
|
||||
const u8 *addr[1];
|
||||
@ -49,7 +46,7 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||
int res;
|
||||
size_t attr_len;
|
||||
const struct dpp_curve_params *own_curve;
|
||||
EVP_PKEY *own_key;
|
||||
struct crypto_ec_key *own_key;
|
||||
struct wpabuf *a_nonce = NULL, *e_id = NULL;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Build Reconfig Announcement frame");
|
||||
@ -61,16 +58,15 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
p = csign_key;
|
||||
csign = d2i_PUBKEY(NULL, &p, csign_key_len);
|
||||
csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
|
||||
if (!csign) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"DPP: Failed to parse local C-sign-key information");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uncomp = dpp_get_pubkey_point(csign, 1);
|
||||
EVP_PKEY_free(csign);
|
||||
uncomp = crypto_ec_key_get_pubkey_point(csign, 1);
|
||||
crypto_ec_key_deinit(csign);
|
||||
if (!uncomp)
|
||||
goto fail;
|
||||
addr[0] = wpabuf_head(uncomp);
|
||||
@ -88,8 +84,8 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
a_nonce = dpp_get_pubkey_point(id->a_nonce, 0);
|
||||
e_id = dpp_get_pubkey_point(id->e_prime_id, 0);
|
||||
a_nonce = crypto_ec_key_get_pubkey_point(id->a_nonce, 0);
|
||||
e_id = crypto_ec_key_get_pubkey_point(id->e_prime_id, 0);
|
||||
if (!a_nonce || !e_id)
|
||||
goto fail;
|
||||
|
||||
@ -126,7 +122,7 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||
fail:
|
||||
wpabuf_free(a_nonce);
|
||||
wpabuf_free(e_id);
|
||||
EVP_PKEY_free(own_key);
|
||||
crypto_ec_key_deinit(own_key);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@ -230,8 +226,8 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||
{
|
||||
struct dpp_authentication *auth;
|
||||
const struct dpp_curve_params *curve;
|
||||
EVP_PKEY *a_nonce, *e_prime_id;
|
||||
EC_POINT *e_id;
|
||||
struct crypto_ec_key *a_nonce, *e_prime_id;
|
||||
struct crypto_ec_point *e_id;
|
||||
|
||||
curve = dpp_get_curve_ike_group(group);
|
||||
if (!curve) {
|
||||
@ -260,13 +256,13 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||
e_prime_id = dpp_set_pubkey_point(conf->csign, e_id_attr, e_id_len);
|
||||
if (!e_prime_id) {
|
||||
wpa_printf(MSG_INFO, "DPP: Invalid E'-id");
|
||||
EVP_PKEY_free(a_nonce);
|
||||
crypto_ec_key_deinit(a_nonce);
|
||||
return NULL;
|
||||
}
|
||||
dpp_debug_print_key("E'-id", e_prime_id);
|
||||
e_id = dpp_decrypt_e_id(conf->pp_key, a_nonce, e_prime_id);
|
||||
EVP_PKEY_free(a_nonce);
|
||||
EVP_PKEY_free(e_prime_id);
|
||||
crypto_ec_key_deinit(a_nonce);
|
||||
crypto_ec_key_deinit(e_prime_id);
|
||||
if (!e_id) {
|
||||
wpa_printf(MSG_INFO, "DPP: Could not decrypt E'-id");
|
||||
return NULL;
|
||||
@ -275,7 +271,7 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||
* Enrollee has already been started and is waiting for updated
|
||||
* configuration instead of replying again before such configuration
|
||||
* becomes available */
|
||||
EC_POINT_clear_free(e_id);
|
||||
crypto_ec_point_deinit(e_id, 1);
|
||||
|
||||
auth = dpp_alloc_auth(dpp, msg_ctx);
|
||||
if (!auth)
|
||||
@ -341,7 +337,7 @@ static int dpp_reconfig_build_resp(struct dpp_authentication *auth,
|
||||
wpabuf_put_le16(clear, wpabuf_len(conn_status));
|
||||
wpabuf_put_buf(clear, conn_status);
|
||||
|
||||
pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
if (!pr)
|
||||
goto fail;
|
||||
|
||||
|
@ -671,10 +671,8 @@ static int dpp_controller_rx_auth_req(struct dpp_connection *conn,
|
||||
}
|
||||
|
||||
if (dpp_set_configurator(conn->auth,
|
||||
conn->ctrl->configurator_params) < 0) {
|
||||
dpp_connection_remove(conn);
|
||||
conn->ctrl->configurator_params) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dpp_tcp_send_msg(conn, conn->auth->resp_msg);
|
||||
}
|
||||
@ -700,7 +698,6 @@ static int dpp_controller_rx_auth_resp(struct dpp_connection *conn,
|
||||
return 0;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
|
||||
dpp_connection_remove(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -862,7 +859,6 @@ static int dpp_controller_rx_presence_announcement(struct dpp_connection *conn,
|
||||
return -1;
|
||||
if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
|
||||
dpp_auth_deinit(auth);
|
||||
dpp_connection_remove(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1723,6 +1719,13 @@ void dpp_controller_stop(struct dpp_global *dpp)
|
||||
}
|
||||
|
||||
|
||||
void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx)
|
||||
{
|
||||
if (dpp && dpp->controller && dpp->controller->cb_ctx == cb_ctx)
|
||||
dpp_controller_stop(dpp);
|
||||
}
|
||||
|
||||
|
||||
static bool dpp_tcp_peer_id_match(struct dpp_authentication *auth,
|
||||
unsigned int id)
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ int allowed_ht40_channel_pair(enum hostapd_hw_mode mode,
|
||||
{
|
||||
int ok, first;
|
||||
int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
|
||||
149, 157, 165, 184, 192 };
|
||||
149, 157, 165, 173, 184, 192 };
|
||||
size_t k;
|
||||
int ht40_plus, pri_chan, sec_chan;
|
||||
|
||||
@ -405,7 +405,7 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
int center_segment1, u32 vht_caps,
|
||||
struct he_capabilities *he_cap)
|
||||
{
|
||||
if (!he_cap)
|
||||
if (!he_cap || !he_cap->he_supported)
|
||||
he_enabled = 0;
|
||||
os_memset(data, 0, sizeof(*data));
|
||||
data->mode = mode;
|
||||
@ -417,7 +417,16 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
data->sec_channel_offset = sec_channel_offset;
|
||||
data->center_freq1 = freq + sec_channel_offset * 10;
|
||||
data->center_freq2 = 0;
|
||||
data->bandwidth = sec_channel_offset ? 40 : 20;
|
||||
if (oper_chwidth == CHANWIDTH_80MHZ)
|
||||
data->bandwidth = 80;
|
||||
else if (oper_chwidth == CHANWIDTH_160MHZ ||
|
||||
oper_chwidth == CHANWIDTH_80P80MHZ)
|
||||
data->bandwidth = 160;
|
||||
else if (sec_channel_offset)
|
||||
data->bandwidth = 40;
|
||||
else
|
||||
data->bandwidth = 20;
|
||||
|
||||
|
||||
hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel,
|
||||
&data->edmg);
|
||||
@ -441,9 +450,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
"Segment 0 center frequency isn't set");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->center_freq1 = data->freq;
|
||||
data->bandwidth = 20;
|
||||
if (!sec_channel_offset)
|
||||
data->center_freq1 = data->freq;
|
||||
} else {
|
||||
int freq1, freq2 = 0;
|
||||
int bw = center_idx_to_bw_6ghz(center_segment0);
|
||||
@ -491,7 +499,10 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
|
||||
if (data->he_enabled) switch (oper_chwidth) {
|
||||
case CHANWIDTH_USE_HT:
|
||||
if (mode == HOSTAPD_MODE_IEEE80211G && sec_channel_offset) {
|
||||
if (sec_channel_offset == 0)
|
||||
break;
|
||||
|
||||
if (mode == HOSTAPD_MODE_IEEE80211G) {
|
||||
if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
|
||||
HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
|
@ -1011,8 +1011,8 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
|
||||
return HOSTAPD_MODE_IEEE80211A;
|
||||
}
|
||||
|
||||
/* 5 GHz, channels 100..140 */
|
||||
if (freq >= 5000 && freq <= 5700) {
|
||||
/* 5 GHz, channels 100..144 */
|
||||
if (freq >= 5500 && freq <= 5720) {
|
||||
if ((freq - 5000) % 5)
|
||||
return NUM_HOSTAPD_MODES;
|
||||
|
||||
@ -1531,6 +1531,16 @@ int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 802.11-2020: Table E-4 - Global operating classes
|
||||
* DFS_50_100_Behavior: 118, 119, 120, 121, 122, 123
|
||||
*/
|
||||
int is_dfs_global_op_class(u8 op_class)
|
||||
{
|
||||
return (op_class >= 118) && (op_class <= 123);
|
||||
}
|
||||
|
||||
|
||||
static int is_11b(u8 rate)
|
||||
{
|
||||
return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
|
||||
@ -1895,9 +1905,9 @@ const struct oper_class_map global_op_class[] = {
|
||||
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, NO_P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, NO_P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, NO_P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
|
||||
{ HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
|
||||
|
||||
@ -2293,6 +2303,30 @@ bool is_6ghz_psc_frequency(int freq)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get_6ghz_sec_channel - Get the relative position of the secondary channel
|
||||
* to the primary channel in 6 GHz
|
||||
* @channel: Primary channel to be checked for (in global op class 131)
|
||||
* Returns: 1 = secondary channel above, -1 = secondary channel below
|
||||
*/
|
||||
|
||||
int get_6ghz_sec_channel(int channel)
|
||||
{
|
||||
/*
|
||||
* In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
|
||||
* the 40 MHz channels are formed with the channel pairs as (1,5),
|
||||
* (9,13), (17,21)..
|
||||
* The secondary channel for a given primary channel is below the
|
||||
* primary channel for the channels 5, 13, 21.. and it is above the
|
||||
* primary channel for the channels 1, 9, 17..
|
||||
*/
|
||||
|
||||
if (((channel - 1) / 4) % 2)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
|
||||
size_t nei_rep_len)
|
||||
{
|
||||
|
@ -218,6 +218,7 @@ int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
|
||||
int sec_channel, u8 *op_class, u8 *channel);
|
||||
int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
|
||||
u16 num_modes);
|
||||
int is_dfs_global_op_class(u8 op_class);
|
||||
enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
|
||||
|
||||
int supp_rates_11b_only(struct ieee802_11_elems *elems);
|
||||
@ -264,6 +265,7 @@ int center_idx_to_bw_6ghz(u8 idx);
|
||||
bool is_6ghz_freq(int freq);
|
||||
bool is_6ghz_op_class(u8 op_class);
|
||||
bool is_6ghz_psc_frequency(int freq);
|
||||
int get_6ghz_sec_channel(int channel);
|
||||
|
||||
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
|
||||
size_t nei_rep_len);
|
||||
|
@ -1337,6 +1337,7 @@ struct ieee80211_ampe_ie {
|
||||
#define CHANWIDTH_4320MHZ 5
|
||||
#define CHANWIDTH_6480MHZ 6
|
||||
#define CHANWIDTH_8640MHZ 7
|
||||
#define CHANWIDTH_40MHZ_6GHZ 8
|
||||
|
||||
#define HE_NSS_MAX_STREAMS 8
|
||||
|
||||
@ -1360,6 +1361,10 @@ struct ieee80211_ampe_ie {
|
||||
#define DPP_CC_OUI_TYPE 0x1e
|
||||
#define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f
|
||||
#define SAE_PK_OUI_TYPE 0x1f
|
||||
#define QM_IE_VENDOR_TYPE 0x506f9a22
|
||||
#define QM_IE_OUI_TYPE 0x22
|
||||
#define WFA_CAPA_IE_VENDOR_TYPE 0x506f9a23
|
||||
#define WFA_CAPA_OUI_TYPE 0x23
|
||||
|
||||
#define MULTI_AP_SUB_ELEM_TYPE 0x06
|
||||
#define MULTI_AP_TEAR_DOWN BIT(4)
|
||||
@ -2341,6 +2346,26 @@ struct ieee80211_he_mu_edca_parameter_set {
|
||||
/* B7: Reserved if sent by an AP; More Data Ack if sent by a non-AP STA */
|
||||
#define HE_QOS_INFO_MORE_DATA_ACK ((u8) (BIT(7)))
|
||||
|
||||
/*
|
||||
* IEEE Std 802.11-2020 and IEEE Std 802.11ax-2021
|
||||
* 9.4.2.170 Reduced Neighbor Report element
|
||||
*/
|
||||
#define RNR_HEADER_LEN 2
|
||||
#define RNR_TBTT_HEADER_LEN 4
|
||||
#define RNR_TBTT_INFO_COUNT(x) (((x) & 0xf) << 4)
|
||||
#define RNR_TBTT_INFO_COUNT_MAX 16
|
||||
#define RNR_TBTT_INFO_LEN 13
|
||||
#define RNR_NEIGHBOR_AP_OFFSET_UNKNOWN 255
|
||||
/* Figure 9-632a - BSS Parameters subfield format */
|
||||
#define RNR_BSS_PARAM_OCT_RECOMMENDED BIT(0)
|
||||
#define RNR_BSS_PARAM_SAME_SSID BIT(1)
|
||||
#define RNR_BSS_PARAM_MULTIPLE_BSSID BIT(2)
|
||||
#define RNR_BSS_PARAM_TRANSMITTED_BSSID BIT(3)
|
||||
#define RNR_BSS_PARAM_MEMBER_CO_LOCATED_ESS BIT(4)
|
||||
#define RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE BIT(5)
|
||||
#define RNR_BSS_PARAM_CO_LOCATED BIT(6)
|
||||
#define RNR_20_MHZ_PSD_MAX_TXPOWER 255 /* dBm */
|
||||
|
||||
/* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */
|
||||
#define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6
|
||||
#define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7
|
||||
@ -2445,4 +2470,35 @@ enum mscs_description_subelem {
|
||||
*/
|
||||
#define FD_MAX_INTERVAL_6GHZ 20 /* TUs */
|
||||
|
||||
/* Protected Vendor-specific QoS Management Action frame identifiers - WFA */
|
||||
#define QM_ACTION_VENDOR_TYPE 0x506f9a1a
|
||||
#define QM_ACTION_OUI_TYPE 0x1a
|
||||
|
||||
/* QoS Management Action frame OUI subtypes */
|
||||
#define QM_DSCP_POLICY_QUERY 0
|
||||
#define QM_DSCP_POLICY_REQ 1
|
||||
#define QM_DSCP_POLICY_RESP 2
|
||||
|
||||
/* QoS Management attributes */
|
||||
enum qm_attr_id {
|
||||
QM_ATTR_PORT_RANGE = 1,
|
||||
QM_ATTR_DSCP_POLICY = 2,
|
||||
QM_ATTR_TCLAS = 3,
|
||||
QM_ATTR_DOMAIN_NAME = 4,
|
||||
};
|
||||
|
||||
/* DSCP Policy attribute - Request Type */
|
||||
enum dscp_policy_request_type {
|
||||
DSCP_POLICY_REQ_ADD = 0, /* ADD/UPDATE */
|
||||
DSCP_POLICY_REQ_REMOVE = 1,
|
||||
};
|
||||
|
||||
/* Request/Response Control field of DSCP Policy Request/Response frame */
|
||||
#define DSCP_POLICY_CTRL_MORE BIT(0)
|
||||
#define DSCP_POLICY_CTRL_RESET BIT(1)
|
||||
|
||||
/* Wi-Fi Alliance Capabilities element - Capabilities field */
|
||||
#define WFA_CAPA_QM_DSCP_POLICY BIT(0)
|
||||
#define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
|
||||
|
||||
#endif /* IEEE802_11_DEFS_H */
|
||||
|
@ -269,7 +269,7 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
|
||||
u32 life_time,
|
||||
const struct wpa_ptk *ptk)
|
||||
{
|
||||
struct ptksa_cache_entry *entry, *tmp;
|
||||
struct ptksa_cache_entry *entry, *tmp, *tmp2 = NULL;
|
||||
struct os_reltime now;
|
||||
|
||||
if (!ptksa || !ptk || !addr || !life_time || cipher == WPA_CIPHER_NONE)
|
||||
@ -296,21 +296,21 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
|
||||
entry->expiration = now.sec + life_time;
|
||||
|
||||
dl_list_for_each(tmp, &ptksa->ptksa, struct ptksa_cache_entry, list) {
|
||||
if (tmp->expiration > entry->expiration)
|
||||
if (tmp->expiration > entry->expiration) {
|
||||
tmp2 = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the list was empty add to the head; otherwise if the expiration is
|
||||
* later then all other entries, add it to the end of the list;
|
||||
* If the expiration is later then all other or the list is empty
|
||||
* entries, add it to the end of the list;
|
||||
* otherwise add it before the relevant entry.
|
||||
*/
|
||||
if (!tmp)
|
||||
dl_list_add(&ptksa->ptksa, &entry->list);
|
||||
else if (tmp->expiration < entry->expiration)
|
||||
dl_list_add(&tmp->list, &entry->list);
|
||||
if (tmp2)
|
||||
dl_list_add(&tmp2->list, &entry->list);
|
||||
else
|
||||
dl_list_add_tail(&tmp->list, &entry->list);
|
||||
dl_list_add_tail(&ptksa->ptksa, &entry->list);
|
||||
|
||||
ptksa->n_ptksa++;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
|
@ -701,6 +701,8 @@ enum qca_radiotap_vendor_ids {
|
||||
* The host driver selects Tx VDEV, and notifies user. The attributes
|
||||
* used with this event are defined in enum
|
||||
* qca_wlan_vendor_attr_mbssid_tx_vdev_status.
|
||||
* This event contains Tx VDEV group information, other VDEVs
|
||||
* interface index, and status information.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to
|
||||
* configure the concurrent session policies when multiple STA interfaces
|
||||
@ -719,6 +721,40 @@ enum qca_radiotap_vendor_ids {
|
||||
* to get DFS radar history from the driver to userspace. The driver
|
||||
* returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an
|
||||
* array of nested entries.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to
|
||||
* enable/disable mDNS offload to the firmware. The attributes used with
|
||||
* this command are defined in enum qca_wlan_vendor_attr_mdns_offload.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
|
||||
* to set packet monitor mode that aims to send the specified set of TX and
|
||||
* RX frames on the current client interface to an active monitor
|
||||
* interface. If this monitor mode is set, the driver will send the
|
||||
* configured frames, from the interface on which the command is issued, to
|
||||
* an active monitor interface. The attributes used with this command are
|
||||
* defined in enum qca_wlan_vendor_attr_set_monitor_mode.
|
||||
*
|
||||
* Though the monitor mode is configured for the respective
|
||||
* Data/Management/Control frames, it is up to the respective WLAN
|
||||
* driver/firmware/hardware designs to consider the possibility of sending
|
||||
* these frames over the monitor interface. For example, the Control frames
|
||||
* are handled within the hardware and thus passing such frames over the
|
||||
* monitor interface is left to the respective designs.
|
||||
*
|
||||
* Also, this monitor mode is governed to behave accordingly in
|
||||
* suspend/resume states. If the firmware handles any of such frames in
|
||||
* suspend state without waking up the host and if the monitor mode is
|
||||
* configured to notify all such frames, the firmware is expected to resume
|
||||
* the host and forward the respective frames to the monitor interface.
|
||||
* Please note that such a request to get the frames over the monitor
|
||||
* interface will have a definite power implication.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
|
||||
* as a request to set the driver/firmware with the parameters to trigger
|
||||
* the roaming events, and also used by the driver/firmware to pass on the
|
||||
* various roam events to userspace.
|
||||
* Applicable only for the STA mode. The attributes used with this command
|
||||
* are defined in enum qca_wlan_vendor_attr_roam_events.
|
||||
*/
|
||||
enum qca_nl80211_vendor_subcmds {
|
||||
QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
|
||||
@ -908,6 +944,10 @@ enum qca_nl80211_vendor_subcmds {
|
||||
QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197,
|
||||
QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199,
|
||||
QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200,
|
||||
/* 201 - reserved for QCA */
|
||||
QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
|
||||
QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
|
||||
};
|
||||
|
||||
enum qca_wlan_vendor_attr {
|
||||
@ -1146,7 +1186,7 @@ enum qca_roaming_policy {
|
||||
* @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel
|
||||
* or environment being very noisy or congested.
|
||||
*
|
||||
* @QCA_ROAM_REASON_EXPLICIT_REQUEST: Roam triggered due to an explicit request
|
||||
* @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request
|
||||
* from the user (user space).
|
||||
*
|
||||
* @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from
|
||||
@ -1154,6 +1194,26 @@ enum qca_roaming_policy {
|
||||
*
|
||||
* @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization
|
||||
* breaching out the configured threshold.
|
||||
*
|
||||
* @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS
|
||||
* transition request.
|
||||
*
|
||||
* @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no
|
||||
* data activity with the AP and the current RSSI falls below a certain
|
||||
* threshold.
|
||||
*
|
||||
* @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or
|
||||
* Disassociation frames received from the connected AP.
|
||||
*
|
||||
* @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan
|
||||
* that happens when there is no candidate AP found during the poor RSSI scan
|
||||
* trigger.
|
||||
*
|
||||
* @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results
|
||||
* obtained from an external scan (not aimed at roaming).
|
||||
*
|
||||
* @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is
|
||||
* established when the station is connected in the 2.4 GHz band.
|
||||
*/
|
||||
enum qca_roam_reason {
|
||||
QCA_ROAM_REASON_UNKNOWN,
|
||||
@ -1165,6 +1225,12 @@ enum qca_roam_reason {
|
||||
QCA_ROAM_REASON_USER_TRIGGER,
|
||||
QCA_ROAM_REASON_BTM,
|
||||
QCA_ROAM_REASON_BSS_LOAD,
|
||||
QCA_ROAM_REASON_WTC,
|
||||
QCA_ROAM_REASON_IDLE,
|
||||
QCA_ROAM_REASON_DISCONNECTION,
|
||||
QCA_ROAM_REASON_PERIODIC_TIMER,
|
||||
QCA_ROAM_REASON_BACKGROUND_SCAN,
|
||||
QCA_ROAM_REASON_BT_ACTIVITY,
|
||||
};
|
||||
|
||||
enum qca_wlan_vendor_attr_roam_auth {
|
||||
@ -1384,6 +1450,11 @@ enum qca_wlan_vendor_attr_p2p_listen_offload {
|
||||
* Used with event to notify the EDMG channel number selected in ACS
|
||||
* operation.
|
||||
* EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16).
|
||||
* Used with event to notify the puncture pattern selected in ACS operation.
|
||||
* Encoding for this attribute will follow the convention used in the Disabled
|
||||
* Subchannel Bitmap field of the EHT Operation IE.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_acs_offload {
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
|
||||
@ -1404,6 +1475,7 @@ enum qca_wlan_vendor_attr_acs_offload {
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
|
||||
@ -1838,6 +1910,23 @@ enum qca_vendor_element_id {
|
||||
QCA_VENDOR_ELEM_ALLPLAY = 6,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_scan_priority - Specifies the valid values that the
|
||||
* vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take.
|
||||
* @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority
|
||||
* @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority
|
||||
* @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority
|
||||
* @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority
|
||||
* @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority
|
||||
*/
|
||||
enum qca_wlan_vendor_scan_priority {
|
||||
QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0,
|
||||
QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1,
|
||||
QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2,
|
||||
QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3,
|
||||
QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes
|
||||
*
|
||||
@ -1863,6 +1952,11 @@ enum qca_vendor_element_id {
|
||||
* @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
|
||||
* microseconds. This is a common value which applies across all
|
||||
* frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
|
||||
* @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to
|
||||
* other scan requests. It is a u32 attribute and takes values from enum
|
||||
* qca_wlan_vendor_scan_priority. This is an optional attribute.
|
||||
* If this attribute is not configured, the driver shall use
|
||||
* QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_scan {
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
|
||||
@ -1878,6 +1972,7 @@ enum qca_wlan_vendor_attr_scan {
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
|
||||
@ -2459,6 +2554,19 @@ enum qca_wlan_vendor_attr_config {
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80,
|
||||
|
||||
/*
|
||||
* 8-bit unsigned value. This attribute can be used to configure the
|
||||
* firmware to enable/disable ARP/NS offload feature. Possible values
|
||||
* for this attribute are 0-Disable and 1-Enable.
|
||||
*
|
||||
* This attribute is only applicable for STA/P2P-Client interface,
|
||||
* and is optional, default behavior is ARP/NS offload enabled.
|
||||
*
|
||||
* This attribute can be set in disconnected and connected state, and
|
||||
* will restore to the default behavior if the interface is closed.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
|
||||
@ -3882,6 +3990,10 @@ enum qca_wlan_vendor_attr_ll_stats_results {
|
||||
* are 0-100.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
|
||||
/* u8 value representing the time slicing duty cycle percentage.
|
||||
* Possible values are 0-100.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
|
||||
@ -4659,6 +4771,44 @@ enum qca_vendor_attr_roam_candidate_selection_criteria {
|
||||
* threshold value specified by the
|
||||
* QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value.
|
||||
* Carries bitmask value of bits from &enum qca_set_band and represents
|
||||
* all the bands in which roaming is allowed. The configuration is valid
|
||||
* until next disconnection. If this attribute is not present, the
|
||||
* existing configuration shall be used. By default, roaming is allowed on
|
||||
* all bands supported by the local device. When the value is set to
|
||||
* %QCA_SETBAND_AUTO, all supported bands shall be enabled.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz
|
||||
* bands. If this attribute is not configured, the driver shall proceed
|
||||
* with default behavior.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. Scan dwell time for passive channels in the 5 GHz
|
||||
* band. If this attribute is not configured, the driver shall proceed with
|
||||
* default behavior.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. The minimum duration to stay on the connected AP
|
||||
* channel during the channel scanning. If this attribute is not
|
||||
* configured, the driver shall proceed with default behavior.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. The maximum duration for which the radio can scan
|
||||
* foreign channels consecutively without coming back to home channel. If
|
||||
* this attribute is not configured, the driver shall proceed with default
|
||||
* behavior.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. Scan dwell time for 6G Preferred Scanning Channels.
|
||||
* If this attribute is not configured, the driver shall proceed with
|
||||
* default behavior.
|
||||
*
|
||||
* @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds.
|
||||
* Optional parameter. Scan dwell time for 6G Non Preferred Scanning
|
||||
* Channels. If this attribute is not configured, the driver shall proceed
|
||||
* with default behavior.
|
||||
*/
|
||||
enum qca_vendor_attr_roam_control {
|
||||
QCA_ATTR_ROAM_CONTROL_ENABLE = 1,
|
||||
@ -4677,6 +4827,13 @@ enum qca_vendor_attr_roam_control {
|
||||
QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14,
|
||||
QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15,
|
||||
QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16,
|
||||
QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17,
|
||||
QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18,
|
||||
QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19,
|
||||
QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20,
|
||||
QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21,
|
||||
QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22,
|
||||
QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23,
|
||||
|
||||
/* keep last */
|
||||
QCA_ATTR_ROAM_CONTROL_AFTER_LAST,
|
||||
@ -6284,6 +6441,14 @@ enum qca_wlan_vendor_attr_spectral_scan {
|
||||
* u32 attribute.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29,
|
||||
/* This attribute specifies the bandwidth to be used for spectral scan
|
||||
* operation. This is an u8 attribute and uses the values in enum
|
||||
* nl80211_chan_width. This is an optional attribute.
|
||||
* If this attribute is not populated, the driver should configure the
|
||||
* spectral scan bandwidth to the maximum value supported by the target
|
||||
* for the current operating bandwidth.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30,
|
||||
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX =
|
||||
@ -6394,6 +6559,14 @@ enum qca_wlan_vendor_attr_spectral_cap {
|
||||
* u32 attribute.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18,
|
||||
/* Flag attribute to indicate agile spectral scan capability
|
||||
* for 320 MHz mode.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19,
|
||||
/* Number of spectral detectors used for scan in 320 MHz.
|
||||
* u32 attribute.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20,
|
||||
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
|
||||
@ -7303,6 +7476,15 @@ enum qca_wlan_vendor_attr_thermal_cmd {
|
||||
* there is any critical ongoing operation.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3,
|
||||
/* Nested attribute, the driver/firmware uses this attribute to report
|
||||
* thermal statistics of different thermal levels to userspace when
|
||||
* requested using the
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command
|
||||
* type. This attribute contains a nested array of records of thermal
|
||||
* statistics of multiple levels. The attributes used inside this nested
|
||||
* attribute are defined in enum qca_wlan_vendor_attr_thermal_stats.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST,
|
||||
@ -7331,6 +7513,13 @@ enum qca_wlan_vendor_attr_thermal_cmd {
|
||||
* @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current
|
||||
* thermal level from the driver/firmware. The driver should respond with a
|
||||
* thermal level defined in enum qca_wlan_vendor_thermal_level.
|
||||
* @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the
|
||||
* current thermal statistics from the driver/firmware. The driver should
|
||||
* respond with statistics of all thermal levels encapsulated in the attribute
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS.
|
||||
* @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear
|
||||
* the current thermal statistics for all thermal levels maintained in the
|
||||
* driver/firmware and start counting from zero again.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_thermal_cmd_type {
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS,
|
||||
@ -7339,6 +7528,8 @@ enum qca_wlan_vendor_attr_thermal_cmd_type {
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -7433,6 +7624,35 @@ enum qca_wlan_vendor_attr_thermal_event {
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes
|
||||
* to get thermal status from the driver/firmware.
|
||||
* enum values are used for NL attributes encapsulated inside the
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute.
|
||||
*
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature
|
||||
* of a thermal level in Celsius. u32 size.
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature
|
||||
* of a thermal level in Celsius. u32 size.
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each
|
||||
* thermal level in milliseconds. u32 size.
|
||||
* QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number
|
||||
* of times the temperature crossed into the temperature range defined by the
|
||||
* thermal level from both higher and lower directions. u32 size.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_thermal_stats {
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum he_fragmentation_val - HE fragmentation support values
|
||||
* Indicates level of dynamic fragmentation that is supported by
|
||||
@ -8158,6 +8378,24 @@ enum qca_wlan_vendor_attr_wifi_test_config {
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
|
||||
|
||||
/* 8-bit unsigned value to configure the driver/firmware to enable or
|
||||
* disable Rx control frame to MultiBSS subfield in the HE MAC
|
||||
* capabilities information field.
|
||||
* 0 - Disable Rx control frame to MultiBSS subfield
|
||||
* 1 - Enable Rx control frame to MultiBSS subfield
|
||||
* This attribute is used to configure the testbed device.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56,
|
||||
|
||||
/* 8-bit unsigned value to configure the driver/firmware to enable or
|
||||
* disable Broadcast TWT support subfield in the HE MAC capabilities
|
||||
* information field.
|
||||
* 0 - Disable Broadcast TWT support subfield
|
||||
* 1 - Enable Broadcast TWT support subfield
|
||||
* This attribute is used to configure the testbed device.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
|
||||
@ -8230,6 +8468,10 @@ enum qca_wlan_vendor_attr_wifi_test_config {
|
||||
*
|
||||
* @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is
|
||||
* ready for a new TWT session setup after it issued a TWT teardown.
|
||||
*
|
||||
* @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required
|
||||
* parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer
|
||||
* the enum qca_wlan_vendor_attr_twt_set_param.
|
||||
*/
|
||||
enum qca_wlan_twt_operation {
|
||||
QCA_WLAN_TWT_SET = 0,
|
||||
@ -8242,6 +8484,7 @@ enum qca_wlan_twt_operation {
|
||||
QCA_WLAN_TWT_CLEAR_STATS = 7,
|
||||
QCA_WLAN_TWT_GET_CAPABILITIES = 8,
|
||||
QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
|
||||
QCA_WLAN_TWT_SET_PARAM = 10,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -8256,7 +8499,8 @@ enum qca_wlan_twt_operation {
|
||||
* @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
|
||||
* parameters configured for TWT. These parameters are represented by
|
||||
* enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
|
||||
* or enum qca_wlan_vendor_attr_twt_stats based on the operation.
|
||||
* enum qca_wlan_vendor_attr_twt_set_param, or
|
||||
* enum qca_wlan_vendor_attr_twt_stats based on the operation.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_config_twt {
|
||||
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
|
||||
@ -8547,9 +8791,13 @@ enum qca_wlan_twt_setup_state {
|
||||
* response.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64)
|
||||
* This field is applicable for TWT response only.
|
||||
* This field contains absolute TSF value of the wake time received
|
||||
* from the TWT responder and is passed to the userspace.
|
||||
* In TWT setup command this field contains absolute TSF that will
|
||||
* be used by TWT requester during setup.
|
||||
* In TWT response this field contains absolute TSF value of the
|
||||
* wake time received from the TWT responder and is passed to
|
||||
* the userspace.
|
||||
* This is an optional parameter for
|
||||
* 1. TWT SET Request
|
||||
* This is a required parameter for
|
||||
* 1. TWT SET Response
|
||||
* 2. TWT GET Response
|
||||
@ -8630,6 +8878,23 @@ enum qca_wlan_twt_setup_state {
|
||||
* indicates that the Broadcast TWT SPs are present until explicitly terminated.
|
||||
* This parameter is used for
|
||||
* 1. TWT SET Request
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8)
|
||||
* This attribute contains the value of the Responder PM Mode subfield (0 or 1)
|
||||
* from TWT response frame.
|
||||
* This parameter is used for
|
||||
* 1. TWT SET Response
|
||||
* 2. TWT GET Response
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32)
|
||||
* This attribute is used to configure the announce timeout value (in us) in
|
||||
* the firmware. This timeout value is only applicable for the announced TWT. If
|
||||
* the timeout value is non-zero the firmware waits up to the timeout value to
|
||||
* use Data frame as an announcement frame. If the timeout value is 0 the
|
||||
* firmware sends an explicit QoS NULL frame as the announcement frame on SP
|
||||
* start. The default value in the firmware is 0.
|
||||
* This parameter is used for
|
||||
* 1. TWT SET Request
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_twt_setup {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
|
||||
@ -8663,6 +8928,9 @@ enum qca_wlan_vendor_attr_twt_setup {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24,
|
||||
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX =
|
||||
@ -8710,6 +8978,9 @@ enum qca_wlan_vendor_attr_twt_setup {
|
||||
* setup request due to channel switch in progress.
|
||||
* @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup
|
||||
* request due to scan in progress.
|
||||
* QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to
|
||||
* terminate an existing TWT session on power save exit request from userspace.
|
||||
* Used on the TWT_TERMINATE notification from the driver/firmware.
|
||||
*/
|
||||
enum qca_wlan_vendor_twt_status {
|
||||
QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
|
||||
@ -8734,6 +9005,7 @@ enum qca_wlan_vendor_twt_status {
|
||||
QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19,
|
||||
QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20,
|
||||
QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21,
|
||||
QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -8989,6 +9261,27 @@ enum qca_wlan_vendor_attr_twt_capability {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for
|
||||
* TWT (Target Wake Time) related parameters. It is used when
|
||||
* %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM.
|
||||
* These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8)
|
||||
* This attribute configures AC parameters to be used for all TWT
|
||||
* sessions in AP mode.
|
||||
* Uses the enum qca_wlan_ac_type values.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_twt_set_param {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
|
||||
* the TWT responder
|
||||
@ -10903,10 +11196,25 @@ enum qca_wlan_vendor_attr_medium_assess {
|
||||
* u8 attribute. Notify the TX VDEV status. Possible values 0, 1
|
||||
* belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV,
|
||||
* 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT:
|
||||
* u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID:
|
||||
* u8 attribute, required. Indicates group id of Tx VDEV.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO:
|
||||
* Nested attribute. This attribute shall be used by the driver to send
|
||||
* group information. The attributes defined in enum
|
||||
* qca_wlan_vendor_attr_mbssid_tx_vdev_group_info
|
||||
* are nested in this attribute.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST,
|
||||
@ -10914,6 +11222,27 @@ enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used
|
||||
* inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX:
|
||||
* u32 attribute, required. Contains interface index.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS:
|
||||
* u8 attribute, required. 0 - means vdev is in down state.
|
||||
* 1 - means vdev is in up state.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info {
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2,
|
||||
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies
|
||||
*
|
||||
@ -11129,4 +11458,330 @@ enum qca_wlan_vendor_attr_radar_history {
|
||||
QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_mdns_offload - Attributes used by
|
||||
* %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag)
|
||||
* Enable mDNS offload. This attribute is mandatory to enable
|
||||
* mDNS offload feature. If this attribute is not present, mDNS offload
|
||||
* is disabled.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing
|
||||
* one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This
|
||||
* attribute is mandatory when enabling the feature, and not required when
|
||||
* disabling the feature.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing
|
||||
* the following attributes:
|
||||
* %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN
|
||||
* %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT
|
||||
* %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute.
|
||||
* It consists of a hostname and ".local" as the domain name. The character
|
||||
* set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes.
|
||||
* It is used to compare the domain in the "QU" query. Only 1 FQDN is
|
||||
* supported per vdev.
|
||||
* For example: myphone.local
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required
|
||||
* u16 attribute. It specifies the total number of resource records present
|
||||
* in the answer section of the answer payload. This attribute is needed by the
|
||||
* firmware to populate the mDNS response frame for mDNS queries without having
|
||||
* to parse the answer payload.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob
|
||||
* attribute sent by the mdnsResponder from userspace. It contains resource
|
||||
* records of various types (e.g., A, AAAA, PTR, TXT) and service list. This
|
||||
* payload is passed down to the firmware and is transmitted in response to
|
||||
* mDNS queries.
|
||||
* The maximum supported size of the answer payload is 512 bytes.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_mdns_offload {
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* qca_wlan_vendor_monitor_data_frame_type - Represent the various
|
||||
* Data frame types to be sent over the monitor interface.
|
||||
*/
|
||||
enum qca_wlan_vendor_monitor_data_frame_type {
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
|
||||
/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set
|
||||
*/
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
|
||||
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
|
||||
};
|
||||
|
||||
/**
|
||||
* qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
|
||||
* Management frame types to be sent over the monitor interface.
|
||||
* @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames.
|
||||
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames
|
||||
* except the Beacon frame.
|
||||
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
|
||||
* BSSID Beacon frames. Valid only in the connected state.
|
||||
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
|
||||
* the Beacon frames obtained during the scan (off channel and connected
|
||||
* channel), when in connected state.
|
||||
*/
|
||||
|
||||
enum qca_wlan_vendor_monitor_mgmt_frame_type {
|
||||
QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
|
||||
/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set
|
||||
*/
|
||||
QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1),
|
||||
QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
|
||||
QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
|
||||
};
|
||||
|
||||
/**
|
||||
* qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
|
||||
* Control frame types to be sent over the monitor interface.
|
||||
* @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames
|
||||
* @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame
|
||||
*/
|
||||
enum qca_wlan_vendor_monitor_ctrl_frame_type {
|
||||
QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
|
||||
/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set
|
||||
*/
|
||||
QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
|
||||
* vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
|
||||
* monitor mode.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the TX Data frame types to be monitored (u32). These Data frames
|
||||
* are represented by enum qca_wlan_vendor_monitor_data_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the RX Data frame types to be monitored (u32). These Data frames
|
||||
* are represented by enum qca_wlan_vendor_monitor_data_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the TX Management frame types to be monitored (u32). These
|
||||
* Management frames are represented by
|
||||
* enum qca_wlan_vendor_monitor_mgmt_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the RX Management frame types to be monitored (u32). These
|
||||
* Management frames are represented by
|
||||
* enum qca_wlan_vendor_monitor_mgmt_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the TX Control frame types to be monitored (u32). These Control
|
||||
* frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute.
|
||||
* Represents the RX Control frame types to be monitored (u32). These Control
|
||||
* frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32
|
||||
* attribute.
|
||||
* Represents the interval in milliseconds only for the connected Beacon frames,
|
||||
* expecting the connected BSS's Beacon frames to be sent on the monitor
|
||||
* interface at this specific interval.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_set_monitor_mode
|
||||
{
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
|
||||
* Bits will be set to 1 if the corresponding state is enabled.
|
||||
*
|
||||
* @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
|
||||
* @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
|
||||
*/
|
||||
enum qca_wlan_vendor_roam_scan_state {
|
||||
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
|
||||
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_roam_event_type - Roam event type flags.
|
||||
* Bits will be set to 1 if the corresponding event is notified.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
|
||||
* carries the trigger reason. When set, it is expected that the roam event
|
||||
* carries the respective reason via the attribute
|
||||
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
|
||||
* the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
|
||||
* carries the roam fail reason. When set, it is expected that the roam event
|
||||
* carries the respective reason via the attribute
|
||||
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
|
||||
* BSSID, RSSI, frequency info of the AP to which the roam was attempted.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
|
||||
* event carries the roam invoke fail reason. When set, it is expected that
|
||||
* the roam event carries the respective reason via the attribute
|
||||
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
|
||||
* carries the roam scan state. When set, it is expected that the roam event
|
||||
* carries the respective scan state via the attribute
|
||||
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
|
||||
* frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
|
||||
*/
|
||||
enum qca_wlan_vendor_roam_event_type {
|
||||
QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
|
||||
QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
|
||||
QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
|
||||
QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
|
||||
* Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
|
||||
* representing the BSSID of the AP to which the roam is attempted.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
|
||||
* in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
|
||||
* attempted.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz
|
||||
* on which the roam is attempted.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
|
||||
* STA mode only. This represents the roam fail reason for the last failed
|
||||
* roaming attempt by the firmware for the specific BSSID. Different roam
|
||||
* failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_roam_events_candidate_info {
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_roam_events - Used by the
|
||||
* vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
|
||||
* roam events to the driver or notify these events from the driver.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
|
||||
* driver/firmware to enable/disable the notification of roam events. It's a
|
||||
* mandatory attribute and used only in the request from the userspace to the
|
||||
* host driver. 1-Enable, 0-Disable.
|
||||
* If the roaming is totally offloaded to the firmware, this request when
|
||||
* enabled shall mandate the firmware to notify all the relevant roam events
|
||||
* represented by the below attributes. If the host is in the suspend mode,
|
||||
* the behavior of the firmware to notify these events is guided by
|
||||
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
|
||||
* these events in the suspend state, the firmware is expected to wake up the
|
||||
* host before the respective events are notified. Please note that such a
|
||||
* request to get the events in the suspend state will have a definite power
|
||||
* implication.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
|
||||
* that the roam events need to be notified in the suspend state too. By
|
||||
* default, these roam events are notified in the resume state. With this flag,
|
||||
* the roam events are notified in both resume and suspend states.
|
||||
* This attribute is used in the request from the userspace to the host driver.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
|
||||
* Represents the different roam event types, signified by the enum
|
||||
* qca_wlan_vendor_roam_event_type.
|
||||
* Each bit of this attribute represents the different roam even types reported
|
||||
* through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
|
||||
* mode only. This represents the roam trigger reason for the last roaming
|
||||
* attempted by the firmware. Each bit of this attribute represents the
|
||||
* different roam trigger reason code which are defined in enum
|
||||
* qca_vendor_roam_triggers.
|
||||
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
|
||||
* STA mode only. This represents the roam invoke fail reason for the last
|
||||
* failed roam invoke. Different roam invoke failure reason codes
|
||||
* are specified in enum qca_vendor_roam_invoke_fail_reasons.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
|
||||
* for which the roam is attempted. Each entry is a nested attribute defined
|
||||
* by enum qca_wlan_vendor_attr_roam_events_candidate_info.
|
||||
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
|
||||
* the scan state on which the roam events need to be notified. The values for
|
||||
* this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
|
||||
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
|
||||
* u32 values. List of frequencies in MHz considered for a roam scan.
|
||||
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
|
||||
*/
|
||||
|
||||
enum qca_wlan_vendor_attr_roam_events
|
||||
{
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1,
|
||||
};
|
||||
|
||||
#endif /* QCA_VENDOR_H */
|
||||
|
@ -286,7 +286,7 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
||||
u8 addrs[2 * ETH_ALEN];
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
u8 *dummy_password, *tmp_password;
|
||||
u8 *stub_password, *tmp_password;
|
||||
int pwd_seed_odd = 0;
|
||||
u8 prime[SAE_MAX_ECC_PRIME_LEN];
|
||||
size_t prime_len;
|
||||
@ -301,10 +301,10 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
||||
|
||||
os_memset(x_bin, 0, sizeof(x_bin));
|
||||
|
||||
dummy_password = os_malloc(password_len);
|
||||
stub_password = os_malloc(password_len);
|
||||
tmp_password = os_malloc(password_len);
|
||||
if (!dummy_password || !tmp_password ||
|
||||
random_get_bytes(dummy_password, password_len) < 0)
|
||||
if (!stub_password || !tmp_password ||
|
||||
random_get_bytes(stub_password, password_len) < 0)
|
||||
goto fail;
|
||||
|
||||
prime_len = sae->tmp->prime_len;
|
||||
@ -354,7 +354,7 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
|
||||
const_time_select_bin(found, dummy_password, password,
|
||||
const_time_select_bin(found, stub_password, password,
|
||||
password_len, tmp_password);
|
||||
if (hmac_sha256_vector(addrs, sizeof(addrs), 2,
|
||||
addr, len, pwd_seed) < 0)
|
||||
@ -415,7 +415,7 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
|
||||
fail:
|
||||
crypto_bignum_deinit(qr, 0);
|
||||
crypto_bignum_deinit(qnr, 0);
|
||||
os_free(dummy_password);
|
||||
os_free(stub_password);
|
||||
bin_clear_free(tmp_password, password_len);
|
||||
crypto_bignum_deinit(x, 1);
|
||||
os_memset(x_bin, 0, sizeof(x_bin));
|
||||
|
@ -3231,6 +3231,11 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
|
||||
pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) {
|
||||
ie->he_capabilities = pos + 3;
|
||||
ie->he_capab_len = pos[1] - 1;
|
||||
} else if (*pos == WLAN_EID_EXTENSION &&
|
||||
pos[1] >= 1 +
|
||||
sizeof(struct ieee80211_he_6ghz_band_cap) &&
|
||||
pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) {
|
||||
ie->he_6ghz_capabilities = pos + 3;
|
||||
} else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
|
||||
ie->qosinfo = pos[2];
|
||||
} else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
|
||||
|
@ -599,6 +599,7 @@ struct wpa_eapol_ie_parse {
|
||||
const u8 *vht_capabilities;
|
||||
const u8 *he_capabilities;
|
||||
size_t he_capab_len;
|
||||
const u8 *he_6ghz_capabilities;
|
||||
const u8 *supp_channels;
|
||||
size_t supp_channels_len;
|
||||
const u8 *supp_oper_classes;
|
||||
|
@ -126,6 +126,10 @@ extern "C" {
|
||||
#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
|
||||
/** Frequency ranges that the driver recommends to avoid */
|
||||
#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
|
||||
/** A new network profile was added (followed by network entry id) */
|
||||
#define WPA_EVENT_NETWORK_ADDED "CTRL-EVENT-NETWORK-ADDED "
|
||||
/** A network profile was removed (followed by prior network entry id) */
|
||||
#define WPA_EVENT_NETWORK_REMOVED "CTRL-EVENT-NETWORK-REMOVED "
|
||||
/** Result of MSCS setup */
|
||||
#define WPA_EVENT_MSCS_RESULT "CTRL-EVENT-MSCS-RESULT "
|
||||
/** WPS overlap detected in PBC mode */
|
||||
@ -157,6 +161,10 @@ extern "C" {
|
||||
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
|
||||
|
||||
#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
|
||||
/** Result of SCS setup */
|
||||
#define WPA_EVENT_SCS_RESULT "CTRL-EVENT-SCS-RESULT "
|
||||
/* Event indicating DSCP policy */
|
||||
#define WPA_EVENT_DSCP_POLICY "CTRL-EVENT-DSCP-POLICY "
|
||||
|
||||
/* WPS ER events */
|
||||
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
|
||||
|
@ -495,6 +495,13 @@ int rc4_skip(const u8 *key, size_t keylen, size_t skip,
|
||||
*/
|
||||
int crypto_get_random(void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_pkcs7_get_certificates - Extract X.509 certificates from PKCS#7 data
|
||||
* @pkcs7: DER encoded PKCS#7 data
|
||||
* Returns: Buffer of the extracted PEM X.509 certificates or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7);
|
||||
|
||||
|
||||
/**
|
||||
* struct crypto_bignum - bignum
|
||||
@ -713,6 +720,14 @@ int crypto_bignum_legendre(const struct crypto_bignum *a,
|
||||
*/
|
||||
struct crypto_ec;
|
||||
|
||||
/**
|
||||
* struct crypto_ec_point - Elliptic curve point
|
||||
*
|
||||
* Internal data structure for EC implementation to represent a point. The
|
||||
* contents is specific to the used crypto library.
|
||||
*/
|
||||
struct crypto_ec_point;
|
||||
|
||||
/**
|
||||
* crypto_ec_init - Initialize elliptic curve context
|
||||
* @group: Identifying number for the ECC group (IANA "Group Description"
|
||||
@ -762,16 +777,26 @@ const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e);
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_get_a - Get 'a' coefficient of an EC group's curve
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: 'a' coefficient (bignum) of the group
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_get_b - Get 'b' coeffiecient of an EC group's curve
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: 'b' coefficient (bignum) of the group
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* struct crypto_ec_point - Elliptic curve point
|
||||
*
|
||||
* Internal data structure for EC implementation to represent a point. The
|
||||
* contents is specific to the used crypto library.
|
||||
* crypto_ec_get_generator - Get generator point of the EC group's curve
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Pointer to generator point
|
||||
*/
|
||||
struct crypto_ec_point;
|
||||
const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_init - Initialize data for an EC point
|
||||
@ -909,25 +934,357 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
|
||||
const struct crypto_ec_point *a,
|
||||
const struct crypto_ec_point *b);
|
||||
|
||||
struct crypto_ecdh;
|
||||
|
||||
struct crypto_ecdh * crypto_ecdh_init(int group);
|
||||
struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y);
|
||||
struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
|
||||
const u8 *key, size_t len);
|
||||
void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);
|
||||
size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh);
|
||||
/**
|
||||
* crypto_ec_point_debug_print - Dump EC point to debug log
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point
|
||||
* @title: Name of the EC point in the trace
|
||||
*/
|
||||
void crypto_ec_point_debug_print(const struct crypto_ec *e,
|
||||
const struct crypto_ec_point *p,
|
||||
const char *title);
|
||||
|
||||
/**
|
||||
* struct crypto_ec_key - Elliptic curve key pair
|
||||
*
|
||||
* Internal data structure for EC key pair. The contents is specific to the used
|
||||
* crypto library.
|
||||
*/
|
||||
struct crypto_ec_key;
|
||||
|
||||
/**
|
||||
* struct crypto_ecdh - Elliptic Curve Diffie–Hellman context
|
||||
*
|
||||
* Internal data structure for ECDH. The contents is specific to the used
|
||||
* crypto library.
|
||||
*/
|
||||
struct crypto_ecdh;
|
||||
|
||||
/**
|
||||
* crypto_ecdh_init - Initialize elliptic curve Diffie–Hellman context
|
||||
* @group: Identifying number for the ECC group (IANA "Group Description"
|
||||
* attribute registry for RFC 2409)
|
||||
* This function generates an ephemeral key pair.
|
||||
* Returns: Pointer to ECDH context or %NULL on failure
|
||||
*/
|
||||
struct crypto_ecdh * crypto_ecdh_init(int group);
|
||||
|
||||
/**
|
||||
* crypto_ecdh_init2 - Initialize elliptic curve Diffie–Hellman context with a
|
||||
* given EC key
|
||||
* @group: Identifying number for the ECC group (IANA "Group Description"
|
||||
* attribute registry for RFC 2409)
|
||||
* @own_key: Our own EC Key
|
||||
* Returns: Pointer to ECDH context or %NULL on failure
|
||||
*/
|
||||
struct crypto_ecdh * crypto_ecdh_init2(int group,
|
||||
struct crypto_ec_key *own_key);
|
||||
|
||||
/**
|
||||
* crypto_ecdh_get_pubkey - Retrieve public key from ECDH context
|
||||
* @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
|
||||
* @inc_y: Whether public key should include y coordinate (explicit form)
|
||||
* or not (compressed form)
|
||||
* Returns: Binary data f the public key or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y);
|
||||
|
||||
/**
|
||||
* crypto_ecdh_set_peerkey - Compute ECDH secret
|
||||
* @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
|
||||
* @inc_y: Whether peer's public key includes y coordinate (explicit form)
|
||||
* or not (compressed form)
|
||||
* @key: Binary data of the peer's public key
|
||||
* @len: Length of the @key buffer
|
||||
* Returns: Binary data with the EDCH secret or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
|
||||
const u8 *key, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_ecdh_deinit - Free ECDH context
|
||||
* @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
|
||||
*/
|
||||
void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);
|
||||
|
||||
/**
|
||||
* crypto_ecdh_prime_len - Get length of the prime in octets
|
||||
* @e: ECDH context from crypto_ecdh_init()
|
||||
* Returns: Length of the prime defining the group
|
||||
*/
|
||||
size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_parse_priv - Initialize EC key pair from ECPrivateKey ASN.1
|
||||
* @der: DER encoding of ASN.1 ECPrivateKey
|
||||
* @der_len: Length of @der buffer
|
||||
* Returns: EC key or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_parse_pub - Initialize EC key pair from SubjectPublicKeyInfo ASN.1
|
||||
* @der: DER encoding of ASN.1 SubjectPublicKeyInfo
|
||||
* @der_len: Length of @der buffer
|
||||
* Returns: EC key or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_set_pub - Initialize an EC public key from EC point coordinates
|
||||
* @group: Identifying number for the ECC group
|
||||
* @x: X coordinate of the public key
|
||||
* @y: Y coordinate of the public key
|
||||
* @len: Length of @x and @y buffer
|
||||
* Returns: EC key or %NULL on failure
|
||||
*
|
||||
* This function initialize an EC key from public key coordinates, in big endian
|
||||
* byte order padded to the length of the prime defining the group.
|
||||
*/
|
||||
struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
|
||||
const u8 *y, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_set_pub_point - Initialize an EC public key from EC point
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @pub: Public key point
|
||||
* Returns: EC key or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec_key *
|
||||
crypto_ec_key_set_pub_point(struct crypto_ec *e,
|
||||
const struct crypto_ec_point *pub);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_gen - Generate EC key pair
|
||||
* @group: Identifying number for the ECC group
|
||||
* Returns: EC key or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec_key * crypto_ec_key_gen(int group);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_deinit - Free EC key
|
||||
* @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen()
|
||||
*/
|
||||
void crypto_ec_key_deinit(struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
|
||||
* Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_get_ecprivate_key - Get ECPrivateKey ASN.1 for a EC key
|
||||
* @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
|
||||
* @include_pub: Whether to include public key in the ASN.1 sequence
|
||||
* Returns: Buffer with DER encoding of ASN.1 ECPrivateKey or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
|
||||
bool include_pub);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_get_pubkey_point - Get public key point coordinates
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
|
||||
* @prefix: Whether output buffer should include the octet to indicate
|
||||
* coordinate form (as defined for SubjectPublicKeyInfo)
|
||||
* Returns: Buffer with coordinates of public key in uncompressed form or %NULL
|
||||
* on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
|
||||
int prefix);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_get_public_key - Get EC public key as an EC point
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
|
||||
* Returns: Public key as an EC point or %NULL on failure
|
||||
*/
|
||||
const struct crypto_ec_point *
|
||||
crypto_ec_key_get_public_key(struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_get_private_key - Get EC private key as a bignum
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
|
||||
* Returns: Private key as a bignum or %NULL on failure
|
||||
*/
|
||||
const struct crypto_bignum *
|
||||
crypto_ec_key_get_private_key(struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_sign - Sign a buffer with an EC key
|
||||
* @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
|
||||
* @data: Data to sign
|
||||
* @len: Length of @data buffer
|
||||
* Returns: Buffer with DER encoding of ASN.1 Ecdsa-Sig-Value or %NULL on failure
|
||||
*/
|
||||
struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_sign_r_s - Sign a buffer with an EC key
|
||||
* @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
|
||||
* @data: Data to sign
|
||||
* @len: Length of @data buffer
|
||||
* Returns: Buffer with the concatenated r and s values. Each value is in big
|
||||
* endian byte order padded to the length of the prime defining the group of
|
||||
* the key.
|
||||
*/
|
||||
struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
|
||||
const u8 *data, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_verify_signature - Verify ECDSA signature
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
|
||||
* @data: Data to be signed
|
||||
* @len: Length of @data buffer
|
||||
* @sig: DER encoding of ASN.1 Ecdsa-Sig-Value
|
||||
* @sig_len: Length of @sig buffer
|
||||
* Returns: 1 if signature is valid, 0 if signature is invalid and -1 on failure
|
||||
*/
|
||||
int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
|
||||
size_t len, const u8 *sig, size_t sig_len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_verify_signature_r_s - Verify signature
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
|
||||
* @data: Data to signed
|
||||
* @len: Length of @data buffer
|
||||
* @r: Binary data, in big endian byte order, of the 'r' field of the ECDSA
|
||||
* signature.
|
||||
* @s: Binary data, in big endian byte order, of the 's' field of the ECDSA
|
||||
* signature.
|
||||
* @r_len: Length of @r buffer
|
||||
* @s_len: Length of @s buffer
|
||||
* Returns: 1 if signature is valid, 0 if signature is invalid, or -1 on failure
|
||||
*/
|
||||
int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
|
||||
const u8 *data, size_t len,
|
||||
const u8 *r, size_t r_len,
|
||||
const u8 *s, size_t s_len);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_group - Get IANA group identifier for an EC key
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
|
||||
* Returns: IANA group identifier and -1 on failure
|
||||
*/
|
||||
int crypto_ec_key_group(struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_cmp - Compare two EC public keys
|
||||
* @key1: Key 1
|
||||
* @key2: Key 2
|
||||
* Returns: 0 if public keys are identical, -1 otherwise
|
||||
*/
|
||||
int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2);
|
||||
|
||||
/**
|
||||
* crypto_ec_key_debug_print - Dump EC key to debug log
|
||||
* @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
|
||||
* @title: Name of the EC point in the trace
|
||||
*/
|
||||
void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
|
||||
const char *title);
|
||||
|
||||
/**
|
||||
* struct crypto_csr - Certification Signing Request
|
||||
*
|
||||
* Internal data structure for CSR. The contents is specific to the used
|
||||
* crypto library.
|
||||
* For now it is assumed that only an EC public key can be used
|
||||
*/
|
||||
struct crypto_csr;
|
||||
|
||||
/**
|
||||
* enum crypto_csr_name - CSR name type
|
||||
*/
|
||||
enum crypto_csr_name {
|
||||
CSR_NAME_CN,
|
||||
CSR_NAME_SN,
|
||||
CSR_NAME_C,
|
||||
CSR_NAME_O,
|
||||
CSR_NAME_OU,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum crypto_csr_attr - CSR attribute
|
||||
*/
|
||||
enum crypto_csr_attr {
|
||||
CSR_ATTR_CHALLENGE_PASSWORD,
|
||||
};
|
||||
|
||||
/**
|
||||
* crypto_csr_init - Initialize empty CSR
|
||||
* Returns: Pointer to CSR data or %NULL on failure
|
||||
*/
|
||||
struct crypto_csr * crypto_csr_init(void);
|
||||
|
||||
/**
|
||||
* crypto_csr_verify - Initialize CSR from CertificationRequest
|
||||
* @req: DER encoding of ASN.1 CertificationRequest
|
||||
*
|
||||
* Returns: Pointer to CSR data or %NULL on failure or if signature is invalid
|
||||
*/
|
||||
struct crypto_csr * crypto_csr_verify(const struct wpabuf *req);
|
||||
|
||||
/**
|
||||
* crypto_csr_deinit - Free CSR structure
|
||||
* @csr: CSR structure from @crypto_csr_init() or crypto_csr_verify()
|
||||
*/
|
||||
void crypto_csr_deinit(struct crypto_csr *csr);
|
||||
|
||||
/**
|
||||
* crypto_csr_set_ec_public_key - Set public key in CSR
|
||||
* @csr: CSR structure from @crypto_csr_init()
|
||||
* @key: EC public key to set as public key in the CSR
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
|
||||
struct crypto_ec_key *key);
|
||||
|
||||
/**
|
||||
* crypto_csr_set_name - Set name entry in CSR SubjectName
|
||||
* @csr: CSR structure from @crypto_csr_init()
|
||||
* @type: Name type to add into the CSR SubjectName
|
||||
* @name: UTF-8 string to write in the CSR SubjectName
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* crypto_csr_set_attribute - Set attribute in CSR
|
||||
* @csr: CSR structure from @crypto_csr_init()
|
||||
* @attr: Attribute identifier
|
||||
* @attr_type: ASN.1 type of @value buffer
|
||||
* @value: Attribute value
|
||||
* @len: length of @value buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
|
||||
int attr_type, const u8 *value, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_csr_get_attribute - Get attribute from CSR
|
||||
* @csr: CSR structure from @crypto_csr_verify()
|
||||
* @attr: Updated with atribute identifier
|
||||
* @len: Updated with length of returned buffer
|
||||
* @type: ASN.1 type of the attribute buffer
|
||||
* Returns: Type, length, and pointer on attribute value or %NULL on failure
|
||||
*/
|
||||
const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
|
||||
enum crypto_csr_attr attr,
|
||||
size_t *len, int *type);
|
||||
|
||||
/**
|
||||
* crypto_csr_sign - Sign CSR and return ASN.1 CertificationRequest
|
||||
* @csr: CSR structure from @crypto_csr_init()
|
||||
* @key: Private key to sign the CSR (for now ony EC key are supported)
|
||||
* @algo: Hash algorithm to use for the signature
|
||||
* Returns: DER encoding of ASN.1 CertificationRequest for the CSR or %NULL on
|
||||
* failure
|
||||
*/
|
||||
struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
|
||||
struct crypto_ec_key *key,
|
||||
enum crypto_hash_alg algo);
|
||||
|
||||
#endif /* CRYPTO_H */
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "tls/pkcs1.h"
|
||||
#include "tls/pkcs8.h"
|
||||
|
||||
/* Dummy structures; these are just typecast to struct crypto_rsa_key */
|
||||
/* Stub structures; these are just typecast to struct crypto_rsa_key */
|
||||
struct crypto_public_key;
|
||||
struct crypto_private_key;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -609,7 +609,7 @@ void crypto_cipher_deinit(struct crypto_cipher *ctx)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS_NFC
|
||||
#ifdef CONFIG_WPS
|
||||
|
||||
static const unsigned char RFC3526_PRIME_1536[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
|
||||
@ -695,6 +695,8 @@ void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS_NFC
|
||||
|
||||
void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
|
||||
{
|
||||
DhKey *ret = NULL;
|
||||
@ -736,6 +738,8 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPS_NFC */
|
||||
|
||||
|
||||
struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
|
||||
const struct wpabuf *own_private)
|
||||
@ -772,7 +776,7 @@ void dh5_free(void *ctx)
|
||||
XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPS_NFC */
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
|
||||
int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
|
||||
|
@ -49,9 +49,9 @@
|
||||
static u32 pool[POOL_WORDS];
|
||||
static unsigned int input_rotate = 0;
|
||||
static unsigned int pool_pos = 0;
|
||||
static u8 dummy_key[20];
|
||||
static u8 stub_key[20];
|
||||
#ifdef __linux__
|
||||
static size_t dummy_key_avail = 0;
|
||||
static size_t stub_key_avail = 0;
|
||||
static int random_fd = -1;
|
||||
#endif /* __linux__ */
|
||||
static unsigned int own_pool_ready = 0;
|
||||
@ -109,13 +109,13 @@ static void random_extract(u8 *out)
|
||||
u32 buf[POOL_WORDS / 2];
|
||||
|
||||
/* First, add hash back to pool to make backtracking more difficult. */
|
||||
hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) pool,
|
||||
hmac_sha1(stub_key, sizeof(stub_key), (const u8 *) pool,
|
||||
sizeof(pool), hash);
|
||||
random_mix_pool(hash, sizeof(hash));
|
||||
/* Hash half the pool to extra data */
|
||||
for (i = 0; i < POOL_WORDS / 2; i++)
|
||||
buf[i] = pool[(pool_pos - i) & POOL_WORDS_MASK];
|
||||
hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) buf,
|
||||
hmac_sha1(stub_key, sizeof(stub_key), (const u8 *) buf,
|
||||
sizeof(buf), hash);
|
||||
/*
|
||||
* Fold the hash to further reduce any potential output pattern.
|
||||
@ -227,7 +227,7 @@ int random_pool_ready(void)
|
||||
* some key derivation operations to proceed.
|
||||
*/
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key))
|
||||
if (stub_key_avail == sizeof(stub_key))
|
||||
return 1; /* Already initialized - good to continue */
|
||||
|
||||
/*
|
||||
@ -238,8 +238,8 @@ int random_pool_ready(void)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_GETRANDOM
|
||||
res = getrandom(dummy_key + dummy_key_avail,
|
||||
sizeof(dummy_key) - dummy_key_avail, GRND_NONBLOCK);
|
||||
res = getrandom(stub_key + stub_key_avail,
|
||||
sizeof(stub_key) - stub_key_avail, GRND_NONBLOCK);
|
||||
if (res < 0) {
|
||||
if (errno == ENOSYS) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
@ -263,8 +263,8 @@ int random_pool_ready(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = read(fd, dummy_key + dummy_key_avail,
|
||||
sizeof(dummy_key) - dummy_key_avail);
|
||||
res = read(fd, stub_key + stub_key_avail,
|
||||
sizeof(stub_key) - stub_key_avail);
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"random: Cannot read from /dev/random: %s",
|
||||
@ -275,10 +275,10 @@ int random_pool_ready(void)
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "random: Got %u/%u random bytes", (unsigned) res,
|
||||
(unsigned) (sizeof(dummy_key) - dummy_key_avail));
|
||||
dummy_key_avail += res;
|
||||
(unsigned) (sizeof(stub_key) - stub_key_avail));
|
||||
stub_key_avail += res;
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
if (stub_key_avail == sizeof(stub_key)) {
|
||||
if (own_pool_ready < MIN_READY_MARK)
|
||||
own_pool_ready = MIN_READY_MARK;
|
||||
random_write_entropy();
|
||||
@ -287,7 +287,7 @@ int random_pool_ready(void)
|
||||
|
||||
wpa_printf(MSG_INFO, "random: Only %u/%u bytes of strong "
|
||||
"random data available",
|
||||
(unsigned) dummy_key_avail, (unsigned) sizeof(dummy_key));
|
||||
(unsigned) stub_key_avail, (unsigned) sizeof(stub_key));
|
||||
|
||||
if (own_pool_ready >= MIN_READY_MARK ||
|
||||
total_collected + 10 * own_pool_ready > MIN_COLLECT_ENTROPY) {
|
||||
@ -331,13 +331,13 @@ static void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
ssize_t res;
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
if (stub_key_avail == sizeof(stub_key)) {
|
||||
random_close_fd();
|
||||
return;
|
||||
}
|
||||
|
||||
res = read(sock, dummy_key + dummy_key_avail,
|
||||
sizeof(dummy_key) - dummy_key_avail);
|
||||
res = read(sock, stub_key + stub_key_avail,
|
||||
sizeof(stub_key) - stub_key_avail);
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
|
||||
"%s", strerror(errno));
|
||||
@ -346,10 +346,10 @@ static void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
|
||||
wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random",
|
||||
(unsigned) res,
|
||||
(unsigned) (sizeof(dummy_key) - dummy_key_avail));
|
||||
dummy_key_avail += res;
|
||||
(unsigned) (sizeof(stub_key) - stub_key_avail));
|
||||
stub_key_avail += res;
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
if (stub_key_avail == sizeof(stub_key)) {
|
||||
random_close_fd();
|
||||
if (own_pool_ready < MIN_READY_MARK)
|
||||
own_pool_ready = MIN_READY_MARK;
|
||||
@ -440,9 +440,9 @@ void random_init(const char *entropy_file)
|
||||
|
||||
#ifdef CONFIG_GETRANDOM
|
||||
{
|
||||
u8 dummy;
|
||||
u8 stub;
|
||||
|
||||
if (getrandom(&dummy, 0, GRND_NONBLOCK) == 0 ||
|
||||
if (getrandom(&stub, 0, GRND_NONBLOCK) == 0 ||
|
||||
errno != ENOSYS) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"random: getrandom() support available");
|
||||
|
@ -3773,6 +3773,7 @@ static int tls_connection_private_key(struct tls_data *data,
|
||||
const u8 *private_key_blob,
|
||||
size_t private_key_blob_len)
|
||||
{
|
||||
BIO *bio;
|
||||
int ok;
|
||||
|
||||
if (private_key == NULL && private_key_blob == NULL)
|
||||
@ -3818,6 +3819,28 @@ static int tls_connection_private_key(struct tls_data *data,
|
||||
break;
|
||||
}
|
||||
|
||||
bio = BIO_new_mem_buf((u8 *) private_key_blob,
|
||||
private_key_blob_len);
|
||||
if (bio) {
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
pkey = PEM_read_bio_PrivateKey(
|
||||
bio, NULL, tls_passwd_cb,
|
||||
(void *) private_key_passwd);
|
||||
if (pkey) {
|
||||
if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"OpenSSL: SSL_use_PrivateKey --> OK");
|
||||
ok = 1;
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free(bio);
|
||||
break;
|
||||
}
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
|
||||
private_key_blob_len,
|
||||
private_key_passwd) == 0) {
|
||||
|
@ -1894,11 +1894,11 @@ struct wpa_driver_capa {
|
||||
*/
|
||||
#define WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P 0x00002000
|
||||
/**
|
||||
* Driver is known to use sane error codes, i.e., when it indicates that
|
||||
* Driver is known to use valid error codes, i.e., when it indicates that
|
||||
* something (e.g., association) fails, there was indeed a failure and the
|
||||
* operation does not end up getting completed successfully later.
|
||||
*/
|
||||
#define WPA_DRIVER_FLAGS_SANE_ERROR_CODES 0x00004000
|
||||
#define WPA_DRIVER_FLAGS_VALID_ERROR_CODES 0x00004000
|
||||
/** Driver supports off-channel TX */
|
||||
#define WPA_DRIVER_FLAGS_OFFCHANNEL_TX 0x00008000
|
||||
/** Driver indicates TX status events for EAPOL Data frames */
|
||||
@ -2151,6 +2151,7 @@ struct hostapd_data;
|
||||
#define STA_DRV_DATA_TX_SHORT_GI BIT(6)
|
||||
#define STA_DRV_DATA_RX_SHORT_GI BIT(7)
|
||||
#define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
|
||||
#define STA_DRV_DATA_CONN_TIME BIT(9)
|
||||
|
||||
struct hostap_sta_driver_data {
|
||||
unsigned long rx_packets, tx_packets;
|
||||
@ -2160,6 +2161,7 @@ struct hostap_sta_driver_data {
|
||||
unsigned long current_tx_rate;
|
||||
unsigned long current_rx_rate;
|
||||
unsigned long inactive_msec;
|
||||
unsigned long connected_sec;
|
||||
unsigned long flags; /* bitfield of STA_DRV_DATA_* */
|
||||
unsigned long num_ps_buf_frames;
|
||||
unsigned long tx_retry_failed;
|
||||
|
@ -268,7 +268,7 @@ const char * driver_flag_to_string(u64 flag)
|
||||
DF2S(P2P_CAPABLE);
|
||||
DF2S(AP_TEARDOWN_SUPPORT);
|
||||
DF2S(P2P_MGMT_AND_NON_P2P);
|
||||
DF2S(SANE_ERROR_CODES);
|
||||
DF2S(VALID_ERROR_CODES);
|
||||
DF2S(OFFCHANNEL_TX);
|
||||
DF2S(EAPOL_TX_STATUS);
|
||||
DF2S(DEAUTH_TX_STATUS);
|
||||
|
@ -55,8 +55,6 @@ enum {
|
||||
PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
|
||||
PRISM2_PARAM_HOST_ENCRYPT = 17,
|
||||
PRISM2_PARAM_HOST_DECRYPT = 18,
|
||||
PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19,
|
||||
PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20,
|
||||
PRISM2_PARAM_HOST_ROAMING = 21,
|
||||
PRISM2_PARAM_BCRX_STA_KEY = 22,
|
||||
PRISM2_PARAM_IEEE_802_1X = 23,
|
||||
|
@ -257,6 +257,33 @@ static int macsec_qca_init_sockets(struct macsec_qca_data *drv, u8 *own_addr)
|
||||
}
|
||||
|
||||
|
||||
static int macsec_qca_secy_id_get(const char *ifname, u32 *secy_id)
|
||||
{
|
||||
#ifdef NSS_MACSEC_SECY_ID_GET_FUNC
|
||||
/* Get secy id from nss macsec driver */
|
||||
return nss_macsec_secy_id_get((u8 *) ifname, secy_id);
|
||||
#else /* NSS_MACSEC_SECY_ID_GET_FUNC */
|
||||
/* Board specific settings */
|
||||
if (os_strcmp(ifname, "eth2") == 0) {
|
||||
*secy_id = 1;
|
||||
} else if (os_strcmp(ifname, "eth3") == 0) {
|
||||
*secy_id = 2;
|
||||
} else if (os_strcmp(ifname, "eth4") == 0 ||
|
||||
os_strcmp(ifname, "eth0") == 0) {
|
||||
*secy_id = 0;
|
||||
} else if (os_strcmp(ifname, "eth5") == 0 ||
|
||||
os_strcmp(ifname, "eth1") == 0) {
|
||||
*secy_id = 1;
|
||||
} else {
|
||||
*secy_id = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif /* NSS_MACSEC_SECY_ID_GET_FUNC */
|
||||
}
|
||||
|
||||
|
||||
static void * macsec_qca_init(void *ctx, const char *ifname)
|
||||
{
|
||||
struct macsec_qca_data *drv;
|
||||
@ -265,13 +292,12 @@ static void * macsec_qca_init(void *ctx, const char *ifname)
|
||||
if (drv == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Board specific settings */
|
||||
if (os_memcmp("eth2", ifname, 4) == 0)
|
||||
drv->secy_id = 1;
|
||||
else if (os_memcmp("eth3", ifname, 4) == 0)
|
||||
drv->secy_id = 2;
|
||||
else
|
||||
drv->secy_id = -1;
|
||||
if (macsec_qca_secy_id_get(ifname, &drv->secy_id)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"macsec_qca: Failed to get secy_id for %s", ifname);
|
||||
os_free(drv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
|
||||
os_free(drv);
|
||||
@ -303,17 +329,13 @@ static void * macsec_qca_hapd_init(struct hostapd_data *hapd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Board specific settings */
|
||||
if (os_memcmp("eth2", params->ifname, 4) == 0)
|
||||
drv->secy_id = 1;
|
||||
else if (os_memcmp("eth3", params->ifname, 4) == 0)
|
||||
drv->secy_id = 2;
|
||||
else if (os_memcmp("eth4", params->ifname, 4) == 0)
|
||||
drv->secy_id = 0;
|
||||
else if (os_memcmp("eth5", params->ifname, 4) == 0)
|
||||
drv->secy_id = 1;
|
||||
else
|
||||
drv->secy_id = -1;
|
||||
if (macsec_qca_secy_id_get(params->ifname, &drv->secy_id)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"macsec_qca: Failed to get secy_id for %s",
|
||||
params->ifname);
|
||||
os_free(drv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drv->common.ctx = hapd;
|
||||
os_strlcpy(drv->common.ifname, params->ifname,
|
||||
|
@ -1111,20 +1111,20 @@ wpa_driver_ndis_associate(void *priv,
|
||||
auth_mode = Ndis802_11AuthModeOpen;
|
||||
priv_mode = Ndis802_11PrivFilterAcceptAll;
|
||||
if (params->wps == WPS_MODE_PRIVACY) {
|
||||
u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
|
||||
u8 stub_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
|
||||
/*
|
||||
* Some NDIS drivers refuse to associate in open mode
|
||||
* configuration due to Privacy field mismatch, so use
|
||||
* a workaround to make the configuration look like
|
||||
* matching one for WPS provisioning.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a "
|
||||
wpa_printf(MSG_DEBUG, "NDIS: Set stub WEP key as a "
|
||||
"workaround to allow driver to associate "
|
||||
"for WPS");
|
||||
wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP,
|
||||
bcast, 0, 1,
|
||||
NULL, 0, dummy_key,
|
||||
sizeof(dummy_key));
|
||||
NULL, 0, stub_key,
|
||||
sizeof(stub_key));
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
} else {
|
||||
@ -2237,10 +2237,10 @@ static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv)
|
||||
|
||||
/*
|
||||
* Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
|
||||
* descriptions. Fill in dummy descriptors to work around this.
|
||||
* descriptions. Fill in stub descriptors to work around this.
|
||||
*/
|
||||
while (num_desc < num_name)
|
||||
desc[num_desc++] = "dummy description";
|
||||
desc[num_desc++] = "stub description";
|
||||
|
||||
if (num_name != num_desc) {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
|
||||
@ -3172,10 +3172,10 @@ wpa_driver_ndis_get_interfaces(void *global_priv)
|
||||
|
||||
/*
|
||||
* Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
|
||||
* descriptions. Fill in dummy descriptors to work around this.
|
||||
* descriptions. Fill in stub descriptors to work around this.
|
||||
*/
|
||||
while (num_desc < num_name)
|
||||
desc[num_desc++] = "dummy description";
|
||||
desc[num_desc++] = "stub description";
|
||||
|
||||
if (num_name != num_desc) {
|
||||
wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
|
||||
|
@ -604,7 +604,7 @@ static int nl_get_multicast_id(struct nl80211_global *global,
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
if (!genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
|
||||
if (!genlmsg_put(msg, 0, 0, global->nlctrl_id,
|
||||
0, 0, CTRL_CMD_GETFAMILY, 0) ||
|
||||
nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
|
||||
nlmsg_free(msg);
|
||||
@ -1883,6 +1883,13 @@ static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
|
||||
goto err;
|
||||
}
|
||||
|
||||
global->nlctrl_id = genl_ctrl_resolve(global->nl, "nlctrl");
|
||||
if (global->nlctrl_id < 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"nl80211: 'nlctrl' generic netlink not found");
|
||||
goto err;
|
||||
}
|
||||
|
||||
global->nl_event = nl_create_handle(global->nl_cb, "event");
|
||||
if (global->nl_event == NULL)
|
||||
goto err;
|
||||
@ -2505,10 +2512,19 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
||||
(nl80211_register_action_frame(bss, (u8 *) "\x05\x02", 2) < 0))
|
||||
ret = -1;
|
||||
|
||||
/* Robust AV SCS Response */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x13\x01", 2) < 0)
|
||||
ret = -1;
|
||||
|
||||
/* Robust AV MSCS Response */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x13\x05", 2) < 0)
|
||||
ret = -1;
|
||||
|
||||
/* Protected QoS Management Action frame */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x7e\x50\x6f\x9a\x1a",
|
||||
5) < 0)
|
||||
ret = -1;
|
||||
|
||||
nl80211_mgmt_handle_register_eloop(bss);
|
||||
|
||||
return ret;
|
||||
@ -4072,7 +4088,7 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
|
||||
freq = bss->freq;
|
||||
}
|
||||
|
||||
if (drv->use_monitor) {
|
||||
if (drv->use_monitor && is_ap_interface(drv->nlmode)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
|
||||
freq, bss->freq);
|
||||
@ -5144,7 +5160,7 @@ static int wpa_driver_nl80211_sta_add(void *priv,
|
||||
/*
|
||||
* cfg80211 validates that AID is non-zero, so we have
|
||||
* to make this a non-zero value for the TDLS case where
|
||||
* a dummy STA entry is used for now and for a station
|
||||
* a stub STA entry is used for now and for a station
|
||||
* that is still not associated.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, " * aid=1 (%s workaround)",
|
||||
@ -7024,6 +7040,7 @@ static int get_sta_handler(struct nl_msg *msg, void *arg)
|
||||
[NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
|
||||
[NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
|
||||
[NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 },
|
||||
[NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 },
|
||||
};
|
||||
struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
|
||||
static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
|
||||
@ -7098,6 +7115,12 @@ static int get_sta_handler(struct nl_msg *msg, void *arg)
|
||||
data->flags |= STA_DRV_DATA_LAST_ACK_RSSI;
|
||||
}
|
||||
|
||||
if (stats[NL80211_STA_INFO_CONNECTED_TIME]) {
|
||||
data->connected_sec =
|
||||
nla_get_u32(stats[NL80211_STA_INFO_CONNECTED_TIME]);
|
||||
data->flags |= STA_DRV_DATA_CONN_TIME;
|
||||
}
|
||||
|
||||
if (stats[NL80211_STA_INFO_TX_BITRATE] &&
|
||||
nla_parse_nested(rate, NL80211_RATE_INFO_MAX,
|
||||
stats[NL80211_STA_INFO_TX_BITRATE],
|
||||
|
@ -32,6 +32,7 @@ struct nl80211_global {
|
||||
struct nl_cb *nl_cb;
|
||||
struct nl_sock *nl;
|
||||
int nl80211_id;
|
||||
int nlctrl_id;
|
||||
int ioctl_sock; /* socket for ioctl() use */
|
||||
|
||||
struct nl_sock *nl_event;
|
||||
|
@ -1389,7 +1389,7 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
||||
WPA_DRIVER_AUTH_SHARED |
|
||||
WPA_DRIVER_AUTH_LEAP;
|
||||
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_VALID_ERROR_CODES;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* EAP proxy - dummy implementation for build testing
|
||||
* EAP proxy - stub implementation for build testing
|
||||
* Copyright (c) 2013 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
|
@ -1760,8 +1760,8 @@ static int eap_teap_process_start(struct eap_sm *sm,
|
||||
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
|
||||
struct wpabuf *resp)
|
||||
static struct wpabuf * eap_teap_add_stub_outer_tlvs(struct eap_teap_data *data,
|
||||
struct wpabuf *resp)
|
||||
{
|
||||
struct wpabuf *resp2;
|
||||
u16 len;
|
||||
@ -1775,11 +1775,11 @@ static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Outer TLVs (dummy Vendor-Specific TLV for testing) */
|
||||
/* Outer TLVs (stub Vendor-Specific TLV for testing) */
|
||||
wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
|
||||
wpabuf_put_be16(data->peer_outer_tlvs, 4);
|
||||
wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
|
||||
wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs",
|
||||
wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add stub Outer TLVs",
|
||||
data->peer_outer_tlvs);
|
||||
|
||||
wpa_hexdump_buf(MSG_DEBUG,
|
||||
@ -1986,7 +1986,7 @@ static struct wpabuf * eap_teap_process(struct eap_sm *sm, void *priv,
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
if (data->test_outer_tlvs && res == 0 && resp &&
|
||||
(flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6)
|
||||
resp = eap_teap_add_dummy_outer_tlvs(data, resp);
|
||||
resp = eap_teap_add_stub_outer_tlvs(data, resp);
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
return resp;
|
||||
|
@ -92,7 +92,7 @@ struct eap_ssl_data {
|
||||
/* could be up to 128 bytes, but only the first 64 bytes are used */
|
||||
#define EAP_TLS_KEY_LEN 64
|
||||
|
||||
/* dummy type used as a flag for UNAUTH-TLS */
|
||||
/* stub type used as a flag for UNAUTH-TLS */
|
||||
#define EAP_UNAUTH_TLS_TYPE 255
|
||||
#define EAP_WFA_UNAUTH_TLS_TYPE 254
|
||||
|
||||
|
@ -68,7 +68,7 @@ struct eap_ssl_data {
|
||||
/* could be up to 128 bytes, but only the first 64 bytes are used */
|
||||
#define EAP_TLS_KEY_LEN 64
|
||||
|
||||
/* dummy type used as a flag for UNAUTH-TLS */
|
||||
/* stub type used as a flag for UNAUTH-TLS */
|
||||
#define EAP_UNAUTH_TLS_TYPE 255
|
||||
#define EAP_WFA_UNAUTH_TLS_TYPE 254
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* WPA Supplicant - Layer2 packet handling example with dummy functions
|
||||
* WPA Supplicant - Layer2 packet handling example with stub functions
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
|
@ -1326,7 +1326,9 @@ void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
|
||||
|
||||
void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
|
||||
{
|
||||
if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
|
||||
if (freq > 0 &&
|
||||
((p2p->drv_in_listen == freq && p2p->in_listen) ||
|
||||
p2p->pending_listen_freq == (unsigned int) freq)) {
|
||||
p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response");
|
||||
return;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
|
||||
|
||||
|
||||
void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
|
||||
const u32 *preferred_freq_list,
|
||||
const unsigned int *preferred_freq_list,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int i, count = 0;
|
||||
|
@ -582,8 +582,8 @@ static void p2p_check_pref_chan_no_recv(struct p2p_data *p2p, int go,
|
||||
&op_channel) < 0)
|
||||
continue; /* cannot happen due to earlier check */
|
||||
for (j = 0; j < msg->channel_list_len; j++) {
|
||||
|
||||
if (op_channel != msg->channel_list[j])
|
||||
if (!msg->channel_list ||
|
||||
op_channel != msg->channel_list[j])
|
||||
continue;
|
||||
|
||||
p2p->op_reg_class = op_class;
|
||||
|
@ -789,7 +789,8 @@ void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
|
||||
int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
|
||||
int all_attr);
|
||||
void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
|
||||
const u32 *preferred_freq_list, u32 size);
|
||||
const unsigned int *preferred_freq_list,
|
||||
unsigned int size);
|
||||
|
||||
/* p2p_sd.c */
|
||||
struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,
|
||||
|
@ -1425,7 +1425,7 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
|
||||
* Save the reported channel list and operating frequency.
|
||||
* Note that the specification mandates that the responder
|
||||
* should include in the channel list only channels reported by
|
||||
* the initiator, so this is only a sanity check, and if this
|
||||
* the initiator, so this is only a validity check, and if this
|
||||
* fails the flow would continue, although it would probably
|
||||
* fail. Same is true for the operating channel.
|
||||
*/
|
||||
|
@ -3057,12 +3057,12 @@ int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay)
|
||||
|
||||
|
||||
/**
|
||||
* ieee802_1x_kay_mkpdu_sanity_check -
|
||||
* Sanity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of
|
||||
* ieee802_1x_kay_mkpdu_validity_check -
|
||||
* Validity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of
|
||||
* MKPDUs)
|
||||
*/
|
||||
static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
|
||||
const u8 *buf, size_t len)
|
||||
static int ieee802_1x_kay_mkpdu_validity_check(struct ieee802_1x_kay *kay,
|
||||
const u8 *buf, size_t len)
|
||||
{
|
||||
struct ieee8023_hdr *eth_hdr;
|
||||
struct ieee802_1x_hdr *eapol_hdr;
|
||||
@ -3215,7 +3215,7 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
|
||||
|
||||
wpa_printf(MSG_DEBUG, "KaY: Decode received MKPDU (ifname=%s)",
|
||||
kay->if_name);
|
||||
if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
|
||||
if (ieee802_1x_kay_mkpdu_validity_check(kay, buf, len))
|
||||
return -1;
|
||||
|
||||
/* handle basic parameter set */
|
||||
|
@ -815,10 +815,7 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
struct radius_client_data *radius = eloop_ctx;
|
||||
struct hostapd_radius_servers *conf = radius->conf;
|
||||
#if defined(__clang_major__) && __clang_major__ >= 11
|
||||
#pragma GCC diagnostic ignored "-Wvoid-pointer-to-enum-cast"
|
||||
#endif
|
||||
RadiusType msg_type = (RadiusType) sock_ctx;
|
||||
RadiusType msg_type = (uintptr_t) sock_ctx;
|
||||
int len, roundtrip;
|
||||
unsigned char buf[RADIUS_MAX_MSG_LEN];
|
||||
struct msghdr msghdr = {0};
|
||||
|
@ -26,6 +26,8 @@ struct rsn_pmksa_cache {
|
||||
|
||||
void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx,
|
||||
enum pmksa_free_reason reason);
|
||||
bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx);
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
@ -57,14 +59,35 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct rsn_pmksa_cache *pmksa = eloop_ctx;
|
||||
struct os_reltime now;
|
||||
struct rsn_pmksa_cache_entry *prev = NULL, *tmp;
|
||||
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
|
||||
|
||||
os_get_reltime(&now);
|
||||
while (pmksa->pmksa && pmksa->pmksa->expiration <= now.sec) {
|
||||
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
|
||||
pmksa->pmksa = entry->next;
|
||||
while (entry && entry->expiration <= now.sec) {
|
||||
if (wpa_key_mgmt_sae(entry->akmp) &&
|
||||
pmksa->is_current_cb(entry, pmksa->ctx)) {
|
||||
/* Do not expire the currently used PMKSA entry for SAE
|
||||
* since there is no convenient mechanism for
|
||||
* reauthenticating during an association with SAE. The
|
||||
* expired entry will be removed after this association
|
||||
* has been lost. */
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"RSN: postpone PMKSA cache entry expiration for SAE with "
|
||||
MACSTR, MAC2STR(entry->aa));
|
||||
prev = entry;
|
||||
entry = entry->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
|
||||
MACSTR, MAC2STR(entry->aa));
|
||||
pmksa_cache_free_entry(pmksa, entry, PMKSA_EXPIRE);
|
||||
if (prev)
|
||||
prev->next = entry->next;
|
||||
else
|
||||
pmksa->pmksa = entry->next;
|
||||
tmp = entry;
|
||||
entry = entry->next;
|
||||
pmksa_cache_free_entry(pmksa, tmp, PMKSA_EXPIRE);
|
||||
}
|
||||
|
||||
pmksa_cache_set_expiration(pmksa);
|
||||
@ -91,13 +114,32 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
|
||||
return;
|
||||
os_get_reltime(&now);
|
||||
sec = pmksa->pmksa->expiration - now.sec;
|
||||
if (sec < 0)
|
||||
if (sec < 0) {
|
||||
sec = 0;
|
||||
if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) &&
|
||||
pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) {
|
||||
/* Do not continue polling for the current PMKSA entry
|
||||
* from SAE to expire every second. Use the expiration
|
||||
* time to the following entry, if any, and wait at
|
||||
* maximum 10 minutes to check again.
|
||||
*/
|
||||
entry = pmksa->pmksa->next;
|
||||
if (entry) {
|
||||
sec = entry->expiration - now.sec;
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
else if (sec > 600)
|
||||
sec = 600;
|
||||
} else {
|
||||
sec = 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
|
||||
|
||||
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
|
||||
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
|
||||
if (entry) {
|
||||
if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
|
||||
sec = pmksa->pmksa->reauth_time - now.sec;
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
@ -378,6 +420,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
|
||||
{
|
||||
struct rsn_pmksa_cache_entry *new_entry;
|
||||
os_time_t old_expiration = old_entry->expiration;
|
||||
os_time_t old_reauth_time = old_entry->reauth_time;
|
||||
const u8 *pmkid = NULL;
|
||||
|
||||
if (wpa_key_mgmt_sae(old_entry->akmp) ||
|
||||
@ -394,6 +437,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
|
||||
|
||||
/* TODO: reorder entries based on expiration time? */
|
||||
new_entry->expiration = old_expiration;
|
||||
new_entry->reauth_time = old_reauth_time;
|
||||
new_entry->opportunistic = 1;
|
||||
|
||||
return new_entry;
|
||||
@ -651,6 +695,8 @@ struct rsn_pmksa_cache_entry * pmksa_cache_head(struct rsn_pmksa_cache *pmksa)
|
||||
struct rsn_pmksa_cache *
|
||||
pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx, enum pmksa_free_reason reason),
|
||||
bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx),
|
||||
void *ctx, struct wpa_sm *sm)
|
||||
{
|
||||
struct rsn_pmksa_cache *pmksa;
|
||||
@ -658,6 +704,7 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
pmksa = os_zalloc(sizeof(*pmksa));
|
||||
if (pmksa) {
|
||||
pmksa->free_cb = free_cb;
|
||||
pmksa->is_current_cb = is_current_cb;
|
||||
pmksa->ctx = ctx;
|
||||
pmksa->sm = sm;
|
||||
}
|
||||
@ -665,4 +712,37 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
return pmksa;
|
||||
}
|
||||
|
||||
|
||||
void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
|
||||
{
|
||||
struct rsn_pmksa_cache_entry *entry;
|
||||
struct os_reltime now;
|
||||
|
||||
if (!pmksa || !pmksa->pmksa)
|
||||
return;
|
||||
|
||||
os_get_reltime(&now);
|
||||
for (entry = pmksa->pmksa; entry; entry = entry->next) {
|
||||
u32 life_time;
|
||||
u8 reauth_threshold;
|
||||
|
||||
if (entry->expiration - now.sec < 1 ||
|
||||
entry->reauth_time - now.sec < 1)
|
||||
continue;
|
||||
|
||||
life_time = entry->expiration - now.sec;
|
||||
reauth_threshold = (entry->reauth_time - now.sec) * 100 /
|
||||
life_time;
|
||||
if (!reauth_threshold)
|
||||
continue;
|
||||
|
||||
wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
|
||||
entry->pmkid,
|
||||
entry->fils_cache_id_set ?
|
||||
entry->fils_cache_id : NULL,
|
||||
entry->pmk, entry->pmk_len, life_time,
|
||||
reauth_threshold, entry->akmp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
@ -59,6 +59,8 @@ enum pmksa_free_reason {
|
||||
struct rsn_pmksa_cache *
|
||||
pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx, enum pmksa_free_reason reason),
|
||||
bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx),
|
||||
void *ctx, struct wpa_sm *sm);
|
||||
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
|
||||
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||
@ -86,12 +88,15 @@ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
|
||||
void *network_ctx, const u8 *aa, int akmp);
|
||||
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
|
||||
const u8 *pmk, size_t pmk_len, bool external_only);
|
||||
void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa);
|
||||
|
||||
#else /* IEEE8021X_EAPOL */
|
||||
|
||||
static inline struct rsn_pmksa_cache *
|
||||
pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx, enum pmksa_free_reason reason),
|
||||
bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx),
|
||||
void *ctx, struct wpa_sm *sm)
|
||||
{
|
||||
return (void *) -1;
|
||||
@ -163,6 +168,10 @@ static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa,
|
||||
{
|
||||
}
|
||||
|
||||
static inline void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
#endif /* PMKSA_CACHE_H */
|
||||
|
@ -138,6 +138,7 @@ struct wpa_tdls_peer {
|
||||
struct ieee80211_vht_capabilities *vht_capabilities;
|
||||
struct ieee80211_he_capabilities *he_capabilities;
|
||||
size_t he_capab_len;
|
||||
struct ieee80211_he_6ghz_band_cap *he_6ghz_band_capabilities;
|
||||
|
||||
u8 qos_info;
|
||||
|
||||
@ -707,6 +708,8 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
|
||||
peer->vht_capabilities = NULL;
|
||||
os_free(peer->he_capabilities);
|
||||
peer->he_capabilities = NULL;
|
||||
os_free(peer->he_6ghz_band_capabilities);
|
||||
peer->he_6ghz_band_capabilities = NULL;
|
||||
os_free(peer->ext_capab);
|
||||
peer->ext_capab = NULL;
|
||||
os_free(peer->supp_channels);
|
||||
@ -1681,6 +1684,33 @@ static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde,
|
||||
}
|
||||
|
||||
|
||||
static int copy_peer_he_6ghz_band_capab(const struct wpa_eapol_ie_parse *kde,
|
||||
struct wpa_tdls_peer *peer)
|
||||
{
|
||||
if (!kde->he_6ghz_capabilities) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"TDLS: No HE 6 GHz band capabilities received");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!peer->he_6ghz_band_capabilities) {
|
||||
peer->he_6ghz_band_capabilities =
|
||||
os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap));
|
||||
if (peer->he_6ghz_band_capabilities == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(peer->he_6ghz_band_capabilities, kde->he_6ghz_capabilities,
|
||||
sizeof(struct ieee80211_he_6ghz_band_cap));
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "TDLS: Peer 6 GHz band HE capabilities",
|
||||
peer->he_6ghz_band_capabilities,
|
||||
sizeof(struct ieee80211_he_6ghz_band_cap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
|
||||
struct wpa_tdls_peer *peer)
|
||||
{
|
||||
@ -1792,6 +1822,7 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
|
||||
peer->vht_capabilities,
|
||||
peer->he_capabilities,
|
||||
peer->he_capab_len,
|
||||
peer->he_6ghz_band_capabilities,
|
||||
peer->qos_info, peer->wmm_capable,
|
||||
peer->ext_capab, peer->ext_capab_len,
|
||||
peer->supp_channels,
|
||||
@ -1928,7 +1959,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
||||
goto error;
|
||||
|
||||
if (copy_peer_vht_capab(&kde, peer) < 0 ||
|
||||
copy_peer_he_capab(&kde, peer) < 0)
|
||||
copy_peer_he_capab(&kde, peer) < 0 ||
|
||||
copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
|
||||
goto error;
|
||||
|
||||
if (copy_peer_ext_capab(&kde, peer) < 0)
|
||||
@ -1957,8 +1989,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
|
||||
"TDLS setup - send own request");
|
||||
peer->initiator = 1;
|
||||
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
|
||||
NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0,
|
||||
NULL, 0);
|
||||
NULL, NULL, 0, NULL, 0, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0);
|
||||
if (wpa_tdls_send_tpk_m1(sm, peer) == -2) {
|
||||
peer = NULL;
|
||||
goto error;
|
||||
@ -2337,7 +2369,8 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
|
||||
goto error;
|
||||
|
||||
if (copy_peer_vht_capab(&kde, peer) < 0 ||
|
||||
copy_peer_he_capab(&kde, peer) < 0)
|
||||
copy_peer_he_capab(&kde, peer) < 0 ||
|
||||
copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
|
||||
goto error;
|
||||
|
||||
if (copy_peer_ext_capab(&kde, peer) < 0)
|
||||
@ -2724,7 +2757,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
|
||||
|
||||
/* add the peer to the driver as a "setup in progress" peer */
|
||||
if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
|
||||
NULL, NULL, 0, 0, 0, NULL, 0, NULL, 0,
|
||||
NULL, NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0,
|
||||
NULL, 0)) {
|
||||
wpa_tdls_disable_peer_link(sm, peer);
|
||||
return -1;
|
||||
|
@ -2903,6 +2903,15 @@ static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
|
||||
}
|
||||
|
||||
|
||||
static bool wpa_sm_pmksa_is_current_cb(struct rsn_pmksa_cache_entry *entry,
|
||||
void *ctx)
|
||||
{
|
||||
struct wpa_sm *sm = ctx;
|
||||
|
||||
return sm->cur_pmksa == entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_sm_init - Initialize WPA state machine
|
||||
* @ctx: Context pointer for callbacks; this needs to be an allocated buffer
|
||||
@ -2926,7 +2935,8 @@ struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
|
||||
sm->dot11RSNAConfigPMKReauthThreshold = 70;
|
||||
sm->dot11RSNAConfigSATimeout = 60;
|
||||
|
||||
sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
|
||||
sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb,
|
||||
wpa_sm_pmksa_is_current_cb, sm, sm);
|
||||
if (sm->pmksa == NULL) {
|
||||
wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
|
||||
"RSN: PMKSA cache initialization failed");
|
||||
@ -3122,9 +3132,11 @@ void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
if (bssid) {
|
||||
pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
|
||||
bssid, sm->own_addr,
|
||||
sm->network_ctx, sm->key_mgmt, NULL);
|
||||
sm->cur_pmksa = pmksa_cache_add(sm->pmksa, pmk, pmk_len,
|
||||
pmkid, NULL, 0, bssid,
|
||||
sm->own_addr,
|
||||
sm->network_ctx, sm->key_mgmt,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5246,3 +5258,10 @@ void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
|
||||
key_mgmt, 0);
|
||||
}
|
||||
#endif /* CONFIG_PASN */
|
||||
|
||||
|
||||
void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
|
||||
{
|
||||
if (sm)
|
||||
pmksa_cache_reconfig(sm->pmksa);
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ struct wpa_sm_ctx {
|
||||
const struct ieee80211_vht_capabilities *vht_capab,
|
||||
const struct ieee80211_he_capabilities *he_capab,
|
||||
size_t he_capab_len,
|
||||
const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
|
||||
u8 qosinfo, int wmm, const u8 *ext_capab,
|
||||
size_t ext_capab_len, const u8 *supp_channels,
|
||||
size_t supp_channels_len,
|
||||
@ -215,6 +216,7 @@ void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
|
||||
const u8 *ptk_kck, size_t ptk_kck_len,
|
||||
const u8 *ptk_kek, size_t ptk_kek_len);
|
||||
int wpa_fils_is_completed(struct wpa_sm *sm);
|
||||
void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm);
|
||||
|
||||
#else /* CONFIG_NO_WPA */
|
||||
|
||||
@ -424,6 +426,10 @@ static inline int wpa_fils_is_completed(struct wpa_sm *sm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NO_WPA */
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
@ -400,6 +400,7 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
|
||||
const struct ieee80211_vht_capabilities *vht_capab,
|
||||
const struct ieee80211_he_capabilities *he_capab,
|
||||
size_t he_capab_len,
|
||||
const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
|
||||
u8 qosinfo, int wmm, const u8 *ext_capab,
|
||||
size_t ext_capab_len, const u8 *supp_channels,
|
||||
size_t supp_channels_len, const u8 *supp_oper_classes,
|
||||
@ -411,7 +412,7 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
|
||||
supp_rates_len, ht_capab,
|
||||
vht_capab,
|
||||
he_capab, he_capab_len,
|
||||
qosinfo, wmm,
|
||||
he_6ghz_capab, qosinfo, wmm,
|
||||
ext_capab, ext_capab_len,
|
||||
supp_channels,
|
||||
supp_channels_len,
|
||||
|
@ -66,12 +66,20 @@ char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
|
||||
* Remove # comments unless they are within a double quoted
|
||||
* string.
|
||||
*/
|
||||
sstart = os_strchr(pos, '"');
|
||||
if (sstart)
|
||||
sstart = os_strrchr(sstart + 1, '"');
|
||||
if (!sstart)
|
||||
sstart = pos;
|
||||
sstart = pos;
|
||||
end = os_strchr(sstart, '#');
|
||||
while (end) {
|
||||
sstart = os_strchr(sstart, '"');
|
||||
if (!sstart || sstart > end)
|
||||
break;
|
||||
sstart = os_strchr(sstart + 1, '"');
|
||||
if (!sstart)
|
||||
break;
|
||||
sstart++;
|
||||
if (sstart > end)
|
||||
end = os_strchr(sstart, '#');
|
||||
}
|
||||
|
||||
if (end)
|
||||
*end-- = '\0';
|
||||
else
|
||||
|
@ -785,21 +785,15 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||
}
|
||||
now_sec = timeout->time.sec;
|
||||
timeout->time.sec += secs;
|
||||
if (timeout->time.sec < now_sec) {
|
||||
/*
|
||||
* Integer overflow - assume long enough timeout to be assumed
|
||||
* to be infinite, i.e., the timeout would never happen.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
|
||||
"ever happen - ignore it", secs);
|
||||
os_free(timeout);
|
||||
return 0;
|
||||
}
|
||||
if (timeout->time.sec < now_sec)
|
||||
goto overflow;
|
||||
timeout->time.usec += usecs;
|
||||
while (timeout->time.usec >= 1000000) {
|
||||
timeout->time.sec++;
|
||||
timeout->time.usec -= 1000000;
|
||||
}
|
||||
if (timeout->time.sec < now_sec)
|
||||
goto overflow;
|
||||
timeout->eloop_data = eloop_data;
|
||||
timeout->user_data = user_data;
|
||||
timeout->handler = handler;
|
||||
@ -817,6 +811,17 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||
dl_list_add_tail(&eloop.timeout, &timeout->list);
|
||||
|
||||
return 0;
|
||||
|
||||
overflow:
|
||||
/*
|
||||
* Integer overflow - assume long enough timeout to be assumed
|
||||
* to be infinite, i.e., the timeout would never happen.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"ELOOP: Too long timeout (secs=%u usecs=%u) to ever happen - ignore it",
|
||||
secs,usecs);
|
||||
os_free(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
int wps_version_number = 0x20;
|
||||
int wps_testing_dummy_cred = 0;
|
||||
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;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
|
||||
extern int wps_version_number;
|
||||
extern int wps_testing_dummy_cred;
|
||||
extern int wps_testing_stub_cred;
|
||||
extern int wps_corrupt_pkhash;
|
||||
extern int wps_force_auth_types_in_use;
|
||||
extern u16 wps_force_auth_types;
|
||||
|
@ -1785,23 +1785,23 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
|
||||
|
||||
use_provided:
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
if (wps_testing_dummy_cred)
|
||||
if (wps_testing_stub_cred)
|
||||
cred = wpabuf_alloc(200);
|
||||
else
|
||||
cred = NULL;
|
||||
if (cred) {
|
||||
struct wps_credential dummy;
|
||||
wpa_printf(MSG_DEBUG, "WPS: Add dummy credential");
|
||||
os_memset(&dummy, 0, sizeof(dummy));
|
||||
os_memcpy(dummy.ssid, "dummy", 5);
|
||||
dummy.ssid_len = 5;
|
||||
dummy.auth_type = WPS_AUTH_WPA2PSK;
|
||||
dummy.encr_type = WPS_ENCR_AES;
|
||||
os_memcpy(dummy.key, "dummy psk", 9);
|
||||
dummy.key_len = 9;
|
||||
os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN);
|
||||
wps_build_credential(cred, &dummy);
|
||||
wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred);
|
||||
struct wps_credential stub;
|
||||
wpa_printf(MSG_DEBUG, "WPS: Add stub credential");
|
||||
os_memset(&stub, 0, sizeof(stub));
|
||||
os_memcpy(stub.ssid, "stub", 5);
|
||||
stub.ssid_len = 5;
|
||||
stub.auth_type = WPS_AUTH_WPA2PSK;
|
||||
stub.encr_type = WPS_ENCR_AES;
|
||||
os_memcpy(stub.key, "stub psk", 9);
|
||||
stub.key_len = 9;
|
||||
os_memcpy(stub.mac_addr, wps->mac_addr_e, ETH_ALEN);
|
||||
wps_build_credential(cred, &stub);
|
||||
wpa_hexdump_buf(MSG_DEBUG, "WPS: Stub Credential", cred);
|
||||
|
||||
wpabuf_put_be16(msg, ATTR_CRED);
|
||||
wpabuf_put_be16(msg, wpabuf_len(cred));
|
||||
|
@ -658,7 +658,7 @@ static int subscription_first_event(struct subscription *s)
|
||||
/*
|
||||
* There has been no events before the subscription. However,
|
||||
* UPnP device architecture specification requires all the
|
||||
* evented variables to be included, so generate a dummy event
|
||||
* evented variables to be included, so generate a stub event
|
||||
* for this particular case using a WSC_ACK and all-zeros
|
||||
* nonces. The ER (UPnP control point) will ignore this, but at
|
||||
* least it will learn that WLANEvent variable will be used in
|
||||
|
@ -366,12 +366,11 @@ CONFIG_AP=y
|
||||
ifdef CONFIG_P2P_STRICT
|
||||
L_CFLAGS += -DCONFIG_P2P_STRICT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_WIFI_DISPLAY
|
||||
L_CFLAGS += -DCONFIG_WIFI_DISPLAY
|
||||
OBJS += wifi_display.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PASN
|
||||
L_CFLAGS += -DCONFIG_PASN
|
||||
|
@ -1864,7 +1864,8 @@ ChangeLog for wpa_supplicant
|
||||
generate, e.g., man pages
|
||||
* l2_packet_linux: use socket type SOCK_DGRAM instead of SOCK_RAW for
|
||||
PF_PACKET in order to prepare for network devices that do not use
|
||||
Ethernet headers (e.g., network stack with native IEEE 802.11 frames)
|
||||
Ethernet headers (e.g., network stack that includes IEEE 802.11
|
||||
header in the frames)
|
||||
* use receipt of EAPOL-Key frame as a lower layer success indication
|
||||
for EAP state machine to allow recovery from dropped EAP-Success
|
||||
frame
|
||||
|
@ -30,9 +30,9 @@ LIBS_p := $(LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
export LIBDIR ?= /usr/local/lib/
|
||||
export INCDIR ?= /usr/local/include/
|
||||
export BINDIR ?= /usr/local/sbin/
|
||||
export LIBDIR ?= /usr/local/lib
|
||||
export INCDIR ?= /usr/local/include
|
||||
export BINDIR ?= /usr/local/sbin
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
@ -389,12 +389,11 @@ CONFIG_AP=y
|
||||
ifdef CONFIG_P2P_STRICT
|
||||
CFLAGS += -DCONFIG_P2P_STRICT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_WIFI_DISPLAY
|
||||
CFLAGS += -DCONFIG_WIFI_DISPLAY
|
||||
OBJS += wifi_display.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PASN
|
||||
CFLAGS += -DCONFIG_PASN
|
||||
@ -1011,7 +1010,6 @@ ifdef CONFIG_PCSC
|
||||
# PC/SC interface for smartcards (USIM, GSM SIM)
|
||||
CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
|
||||
OBJS += ../src/utils/pcsc_funcs.o
|
||||
# -lpthread may not be needed depending on how pcsc-lite was configured
|
||||
ifdef CONFIG_NATIVE_WINDOWS
|
||||
#Once MinGW gets support for WinScard, -lwinscard could be used instead of the
|
||||
#dynamic symbol loading that is now used in pcsc_funcs.c
|
||||
@ -1020,7 +1018,7 @@ else
|
||||
ifdef CONFIG_OSX
|
||||
LIBS += -framework PCSC
|
||||
else
|
||||
LIBS += -lpcsclite -lpthread
|
||||
LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -1077,3 +1077,87 @@ ext:test4@wlan0:0:0:9.679895
|
||||
OK
|
||||
<3>EXT-RADIO-WORK-START 7
|
||||
<3>EXT-RADIO-WORK-TIMEOUT 7
|
||||
|
||||
|
||||
DSCP policy procedures
|
||||
----------------------
|
||||
|
||||
DSCP policy procedures defined in WFA QoS Management-R2 program
|
||||
facilitates AP devices to configure DSCP settings for specific uplink
|
||||
data streams.
|
||||
|
||||
An AP may transmit a DSCP Policy Request frame containing zero or more
|
||||
QoS Management IEs to an associated STA which supports DSCP policy
|
||||
procedures. Each QoS Management element in a DSCP Policy Request frame
|
||||
represents one DSCP policy, and shall include one DSCP Policy attribute
|
||||
including a DSCP Policy ID, Request type, and a DSCP value.
|
||||
|
||||
wpa_supplicant sends control interface event messages consisting details
|
||||
of DSCP policies requested by the AP through a DSCP Policy Request frame
|
||||
to external programs. The format of the control interface event messages
|
||||
is as shown below:
|
||||
|
||||
- Control interface event message format to indicate DSCP request start
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY request_start [clear_all] [more]
|
||||
|
||||
clear_all - AP requested to clear all DSCP policies configured earlier
|
||||
more - AP may request to configure more DSCP policies with new DSCP
|
||||
request
|
||||
|
||||
- Control interface event message format to add new policy
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY add <policy_id> <dscp_value> <ip_version=0|4|6>
|
||||
[protocol] [source ip] [destination_ip]/[domain name] [source port]
|
||||
[[<start_port> <end_port>]/destination port]
|
||||
|
||||
ip_version = 0: Both IPv4 and IPv6
|
||||
= 4: IPv4
|
||||
= 6: IPv6
|
||||
protocol: Internet Protocol Numbers as per IETF RFCs
|
||||
= 6: TCP
|
||||
= 17: UDP
|
||||
= 50: ESP
|
||||
|
||||
- Control interface event message format to remove a particular policy,
|
||||
identified by the policy_id attribute.
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY remove <policy_id>
|
||||
|
||||
- DSCP policy may get rejected due to invalid policy parameters. Ccontrol
|
||||
interface event message format for rejected policy.
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY reject <policy_id>
|
||||
|
||||
- Control interface event message format to indicate end of DSCP request.
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY request_end
|
||||
|
||||
- External applications shall clear active DSCP policies upon receiving
|
||||
"CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
|
||||
|
||||
- Control interface event message format to indicate wpa_supplicant started
|
||||
a timer to wait until the unsolicited DSCP request from the AP.
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY request_wait start
|
||||
|
||||
- Control interface event message format to indicate timeout to receive the
|
||||
unsolicited DSCP request. This event is expected only when an unsolicited
|
||||
DSCP request is not received from the AP before timeout.
|
||||
|
||||
<3>CTRL-EVENT-DSCP-POLICY request_wait end
|
||||
|
||||
DSCP Response:
|
||||
A QoS Management STA that enables DSCP Policy capability shall respond
|
||||
with DSCP response on receipt of a successful DSCP request from its
|
||||
associated AP. wpa_supplicant sends DSCP policy response based on the
|
||||
control interface command received from the user is as below:
|
||||
|
||||
DSCP_RESP <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
|
||||
|
||||
DSCP Query:
|
||||
DSCP Policy Query enables a STA to query its associated AP for DSCP
|
||||
policies applicable to the STA. Currently, this includes support to send
|
||||
a wildcard DSCP query or a DSCP query with a single domain name
|
||||
attribute. The command format for the DSCP query command is as follows:
|
||||
DSCP_QUERY <wildcard>/<domain_name=<string>>
|
||||
|
@ -84,6 +84,11 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
|
||||
/* Use the maximum oper channel width if it's given. */
|
||||
if (ssid->max_oper_chwidth)
|
||||
hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
|
||||
if (hostapd_get_oper_chwidth(conf))
|
||||
ieee80211_freq_to_channel_ext(ssid->frequency, 0,
|
||||
hostapd_get_oper_chwidth(conf),
|
||||
&conf->op_class,
|
||||
&conf->channel);
|
||||
|
||||
if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
|
||||
ieee80211_freq_to_chan(ssid->vht_center_freq2,
|
||||
@ -191,19 +196,79 @@ wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
|
||||
static int get_max_oper_chwidth_6ghz(int chwidth)
|
||||
{
|
||||
switch (chwidth) {
|
||||
case CHANWIDTH_USE_HT:
|
||||
return 20;
|
||||
case CHANWIDTH_40MHZ_6GHZ:
|
||||
return 40;
|
||||
case CHANWIDTH_80MHZ:
|
||||
return 80;
|
||||
case CHANWIDTH_80P80MHZ:
|
||||
case CHANWIDTH_160MHZ:
|
||||
return 160;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void wpas_conf_ap_he_6ghz(struct wpa_supplicant *wpa_s,
|
||||
struct hostapd_hw_modes *mode,
|
||||
struct wpa_ssid *ssid,
|
||||
struct hostapd_config *conf)
|
||||
{
|
||||
bool is_chanwidth_40_80, is_chanwidth_160;
|
||||
int he_chanwidth;
|
||||
|
||||
he_chanwidth =
|
||||
mode->he_capab[wpas_mode_to_ieee80211_mode(
|
||||
ssid->mode)].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
|
||||
is_chanwidth_40_80 = he_chanwidth &
|
||||
HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
|
||||
is_chanwidth_160 = he_chanwidth &
|
||||
HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Enable HE support (p2p_group=%d he_chwidth_cap=%d)",
|
||||
ssid->p2p_group, he_chanwidth);
|
||||
|
||||
if (mode->he_capab[wpas_mode_to_ieee80211_mode(
|
||||
ssid->mode)].he_supported &&
|
||||
ssid->he)
|
||||
conf->ieee80211ax = 1;
|
||||
|
||||
if (is_chanwidth_40_80 && ssid->p2p_group &&
|
||||
get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 40) {
|
||||
conf->secondary_channel =
|
||||
wpas_p2p_get_sec_channel_offset_40mhz(
|
||||
wpa_s, mode, conf->channel);
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Secondary channel offset %d for P2P group",
|
||||
conf->secondary_channel);
|
||||
if (ssid->max_oper_chwidth == CHANWIDTH_40MHZ_6GHZ)
|
||||
ssid->max_oper_chwidth = CHANWIDTH_USE_HT;
|
||||
}
|
||||
|
||||
if ((is_chanwidth_40_80 || is_chanwidth_160) && ssid->p2p_group &&
|
||||
get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 80)
|
||||
wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
|
||||
int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_ssid *ssid,
|
||||
struct hostapd_config *conf)
|
||||
{
|
||||
conf->hw_mode = ieee80211_freq_to_channel_ext(ssid->frequency, 0,
|
||||
ssid->max_oper_chwidth,
|
||||
CHANWIDTH_USE_HT,
|
||||
&conf->op_class,
|
||||
&conf->channel);
|
||||
/* ssid->max_oper_chwidth is not valid in all cases, so fall back to the
|
||||
* less specific mechanism, if needed, at least for now */
|
||||
if (conf->hw_mode == NUM_HOSTAPD_MODES)
|
||||
conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
|
||||
&conf->channel);
|
||||
if (conf->hw_mode == NUM_HOSTAPD_MODES) {
|
||||
wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
|
||||
ssid->frequency);
|
||||
@ -224,7 +289,8 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
|
||||
"Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
|
||||
ssid->frequency, conf->channel);
|
||||
|
||||
mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
|
||||
mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
|
||||
conf->hw_mode, is_6ghz_freq(ssid->frequency));
|
||||
|
||||
/* May drop to IEEE 802.11b if the driver does not support IEEE
|
||||
* 802.11g */
|
||||
@ -255,7 +321,12 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
|
||||
no_ht = 1;
|
||||
}
|
||||
|
||||
if (!no_ht && mode && mode->ht_capab) {
|
||||
if (mode && is_6ghz_freq(ssid->frequency) &&
|
||||
conf->hw_mode == HOSTAPD_MODE_IEEE80211A) {
|
||||
#ifdef CONFIG_P2P
|
||||
wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf);
|
||||
#endif /* CONFIG_P2P */
|
||||
} else if (!no_ht && mode && mode->ht_capab) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Enable HT support (p2p_group=%d 11a=%d ht40_hw_capab=%d ssid->ht40=%d)",
|
||||
ssid->p2p_group,
|
||||
@ -279,8 +350,8 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
|
||||
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
|
||||
ssid->ht40) {
|
||||
conf->secondary_channel =
|
||||
wpas_p2p_get_ht40_mode(wpa_s, mode,
|
||||
conf->channel);
|
||||
wpas_p2p_get_sec_channel_offset_40mhz(
|
||||
wpa_s, mode, conf->channel);
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"HT secondary channel offset %d for P2P group",
|
||||
conf->secondary_channel);
|
||||
@ -530,7 +601,10 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
|
||||
bss->sae_passwords = pw;
|
||||
}
|
||||
|
||||
bss->sae_pwe = wpa_s->conf->sae_pwe;
|
||||
if (ssid->sae_pwe != DEFAULT_SAE_PWE)
|
||||
bss->sae_pwe = ssid->sae_pwe;
|
||||
else
|
||||
bss->sae_pwe = wpa_s->conf->sae_pwe;
|
||||
#endif /* CONFIG_SAE */
|
||||
|
||||
if (wpa_s->conf->go_interworking) {
|
||||
@ -698,6 +772,10 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
|
||||
bss->vendor_elements =
|
||||
wpabuf_dup(wpa_s->conf->ap_vendor_elements);
|
||||
}
|
||||
if (wpa_s->conf->ap_assocresp_elements) {
|
||||
bss->assocresp_elements =
|
||||
wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
|
||||
}
|
||||
|
||||
bss->ftm_responder = wpa_s->conf->ftm_responder;
|
||||
bss->ftm_initiator = wpa_s->conf->ftm_initiator;
|
||||
@ -1748,6 +1826,32 @@ int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd)
|
||||
#endif /* CONFIG_MESH */
|
||||
#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
|
||||
|
||||
|
||||
int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct hostapd_data *hapd;
|
||||
|
||||
if (!wpa_s->ap_iface)
|
||||
return -1;
|
||||
hapd = wpa_s->ap_iface->bss[0];
|
||||
|
||||
wpabuf_free(hapd->conf->assocresp_elements);
|
||||
hapd->conf->assocresp_elements = NULL;
|
||||
if (wpa_s->conf->ap_assocresp_elements) {
|
||||
hapd->conf->assocresp_elements =
|
||||
wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
|
||||
}
|
||||
|
||||
wpabuf_free(hapd->conf->vendor_elements);
|
||||
hapd->conf->vendor_elements = NULL;
|
||||
if (wpa_s->conf->ap_vendor_elements) {
|
||||
hapd->conf->vendor_elements =
|
||||
wpabuf_dup(wpa_s->conf->ap_vendor_elements);
|
||||
}
|
||||
|
||||
return ieee802_11_set_beacon(hapd);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CTRL_IFACE */
|
||||
|
||||
|
||||
|
@ -88,6 +88,7 @@ void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
|
||||
int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
char *buf, size_t len);
|
||||
int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd);
|
||||
int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s);
|
||||
|
||||
void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
|
||||
struct dfs_event *radar);
|
||||
|
@ -2951,6 +2951,7 @@ void wpa_config_free(struct wpa_config *config)
|
||||
os_free(config->ext_password_backend);
|
||||
os_free(config->sae_groups);
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
wpabuf_free(config->ap_assocresp_elements);
|
||||
os_free(config->osu_dir);
|
||||
os_free(config->bgscan);
|
||||
os_free(config->wowlan_triggers);
|
||||
@ -3139,6 +3140,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
|
||||
#endif /* CONFIG_VHT_OVERRIDES */
|
||||
ssid->proactive_key_caching = -1;
|
||||
ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
|
||||
ssid->sae_pwe = DEFAULT_SAE_PWE;
|
||||
#ifdef CONFIG_MACSEC
|
||||
ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
|
||||
#endif /* CONFIG_MACSEC */
|
||||
@ -4909,33 +4911,46 @@ static int wpa_config_process_ap_vendor_elements(
|
||||
struct wpa_config *config, int line, const char *pos)
|
||||
{
|
||||
struct wpabuf *tmp;
|
||||
int len = os_strlen(pos) / 2;
|
||||
u8 *p;
|
||||
|
||||
if (!len) {
|
||||
if (!*pos) {
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
config->ap_vendor_elements = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = wpabuf_parse_bin(pos);
|
||||
if (!tmp) {
|
||||
wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
|
||||
line);
|
||||
return -1;
|
||||
}
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
config->ap_vendor_elements = tmp;
|
||||
|
||||
tmp = wpabuf_alloc(len);
|
||||
if (tmp) {
|
||||
p = wpabuf_put(tmp, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hexstr2bin(pos, p, len)) {
|
||||
wpa_printf(MSG_ERROR, "Line %d: invalid "
|
||||
"ap_vendor_elements", line);
|
||||
wpabuf_free(tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpabuf_free(config->ap_vendor_elements);
|
||||
config->ap_vendor_elements = tmp;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Cannot allocate memory for "
|
||||
"ap_vendor_elements");
|
||||
static int wpa_config_process_ap_assocresp_elements(
|
||||
const struct global_parse_data *data,
|
||||
struct wpa_config *config, int line, const char *pos)
|
||||
{
|
||||
struct wpabuf *tmp;
|
||||
|
||||
if (!*pos) {
|
||||
wpabuf_free(config->ap_assocresp_elements);
|
||||
config->ap_assocresp_elements = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = wpabuf_parse_bin(pos);
|
||||
if (!tmp) {
|
||||
wpa_printf(MSG_ERROR, "Line %d: invalid ap_assocresp_elements",
|
||||
line);
|
||||
return -1;
|
||||
}
|
||||
wpabuf_free(config->ap_assocresp_elements);
|
||||
config->ap_assocresp_elements = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -5155,6 +5170,7 @@ static const struct global_parse_data global_fields[] = {
|
||||
{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
|
||||
{ INT(dtim_period), 0 },
|
||||
{ INT(beacon_int), 0 },
|
||||
{ FUNC(ap_assocresp_elements), 0 },
|
||||
{ FUNC(ap_vendor_elements), 0 },
|
||||
{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
|
||||
{ FUNC(freq_list), 0 },
|
||||
|
@ -1241,6 +1241,17 @@ struct wpa_config {
|
||||
*/
|
||||
struct wpabuf *ap_vendor_elements;
|
||||
|
||||
/**
|
||||
* ap_assocresp_elements: Vendor specific elements for (Re)Association
|
||||
* Response frames
|
||||
*
|
||||
* This parameter can be used to define additional vendor specific
|
||||
* elements for (Re)Association Response frames in AP/P2P GO mode. The
|
||||
* format for these element(s) is a hexdump of the raw information
|
||||
* elements (id+len+payload for one or more elements).
|
||||
*/
|
||||
struct wpabuf *ap_assocresp_elements;
|
||||
|
||||
/**
|
||||
* ignore_old_scan_res - Ignore scan results older than request
|
||||
*
|
||||
|
@ -675,6 +675,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
|
||||
INT(mem_only_psk);
|
||||
STR(sae_password);
|
||||
STR(sae_password_id);
|
||||
write_int(f, "sae_pwe", ssid->sae_pwe, DEFAULT_SAE_PWE);
|
||||
write_proto(f, ssid);
|
||||
write_key_mgmt(f, ssid);
|
||||
INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
|
||||
@ -1364,6 +1365,18 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
||||
}
|
||||
}
|
||||
|
||||
if (config->ap_assocresp_elements) {
|
||||
int i, len = wpabuf_len(config->ap_assocresp_elements);
|
||||
const u8 *p = wpabuf_head_u8(config->ap_assocresp_elements);
|
||||
|
||||
if (len > 0) {
|
||||
fprintf(f, "ap_assocresp_elements=");
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(f, "%02x", *p++);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (config->ignore_old_scan_res)
|
||||
fprintf(f, "ignore_old_scan_res=%d\n",
|
||||
config->ignore_old_scan_res);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file implements dummy example of a configuration backend. None of the
|
||||
* This file implements stub example of a configuration backend. None of the
|
||||
* functions are actually implemented so this can be used as a simple
|
||||
* compilation test or a starting point for a new configuration backend.
|
||||
*/
|
||||
|
@ -46,6 +46,9 @@
|
||||
#define DEFAULT_USER_SELECTED_SIM 1
|
||||
#define DEFAULT_MAX_OPER_CHWIDTH -1
|
||||
|
||||
/* Consider global sae_pwe for SAE mechanism for PWE derivation */
|
||||
#define DEFAULT_SAE_PWE 4
|
||||
|
||||
struct psk_list_entry {
|
||||
struct dl_list list;
|
||||
u8 addr[ETH_ALEN];
|
||||
@ -1156,6 +1159,19 @@ struct wpa_ssid {
|
||||
* configuration.
|
||||
*/
|
||||
bool was_recently_reconfigured;
|
||||
|
||||
/**
|
||||
* sae_pwe - SAE mechanism for PWE derivation
|
||||
*
|
||||
* Internally, special value 4 (DEFAULT_SAE_PWE) is used to indicate
|
||||
* that the parameter is not set and the global sae_pwe value needs to
|
||||
* be considered.
|
||||
*
|
||||
* 0 = hunting-and-pecking loop only
|
||||
* 1 = hash-to-element only
|
||||
* 2 = both hunting-and-pecking loop and hash-to-element enabled
|
||||
*/
|
||||
int sae_pwe;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SSID_H */
|
||||
|
@ -568,10 +568,10 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||
(wps_version_number & 0xf0) >> 4,
|
||||
wps_version_number & 0x0f);
|
||||
}
|
||||
} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
|
||||
wps_testing_dummy_cred = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
|
||||
wps_testing_dummy_cred);
|
||||
} else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
|
||||
wps_testing_stub_cred = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
|
||||
wps_testing_stub_cred);
|
||||
} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
|
||||
wps_corrupt_pkhash = atoi(value);
|
||||
wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
|
||||
@ -830,6 +830,10 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||
wpa_s->sae_commit_override = wpabuf_parse_bin(value);
|
||||
} else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
|
||||
ret = wpas_ctrl_iface_set_dso(wpa_s, value);
|
||||
} else if (os_strcasecmp(cmd, "disable_scs_support") == 0) {
|
||||
wpa_s->disable_scs_support = !!atoi(value);
|
||||
} else if (os_strcasecmp(cmd, "disable_mscs_support") == 0) {
|
||||
wpa_s->disable_mscs_support = !!atoi(value);
|
||||
#ifdef CONFIG_DPP
|
||||
} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
|
||||
os_free(wpa_s->dpp_config_obj_override);
|
||||
@ -918,6 +922,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||
return -1;
|
||||
wnm_set_coloc_intf_elems(wpa_s, elems);
|
||||
#endif /* CONFIG_WNM */
|
||||
} else if (os_strcasecmp(cmd, "enable_dscp_policy_capa") == 0) {
|
||||
wpa_s->enable_dscp_policy_capa = !!atoi(value);
|
||||
} else {
|
||||
value[-1] = '=';
|
||||
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
|
||||
@ -5918,7 +5924,7 @@ static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
|
||||
for (i = 0; p2ps_prov->cpt_priority[i]; i++)
|
||||
p2ps_prov->cpt_mask |= p2ps_prov->cpt_priority[i];
|
||||
|
||||
/* force conncap with tstCap (no sanity checks) */
|
||||
/* force conncap with tstCap (no validity checks) */
|
||||
pos = os_strstr(cmd, "tstCap=");
|
||||
if (pos) {
|
||||
role = strtol(pos + 7, NULL, 16);
|
||||
@ -6122,6 +6128,9 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
|
||||
if (max_oper_chwidth < 0)
|
||||
return -1;
|
||||
|
||||
if (allow_6ghz && chwidth == 40)
|
||||
max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
|
||||
|
||||
pos2 = os_strstr(pos, " ssid=");
|
||||
if (pos2) {
|
||||
char *end;
|
||||
@ -6775,6 +6784,9 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
|
||||
|
||||
allow_6ghz = os_strstr(cmd, " allow_6ghz") != NULL;
|
||||
|
||||
if (allow_6ghz && chwidth == 40)
|
||||
max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
|
||||
|
||||
return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
|
||||
max_oper_chwidth, pref_freq, he, edmg,
|
||||
allow_6ghz);
|
||||
@ -6918,6 +6930,13 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
|
||||
if (max_oper_chwidth < 0)
|
||||
return -1;
|
||||
|
||||
if (allow_6ghz && chwidth == 40)
|
||||
max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
|
||||
|
||||
/* Allow DFS to be used for Autonomous GO */
|
||||
wpa_s->p2p_go_allow_dfs = !!(wpa_s->drv_flags &
|
||||
WPA_DRIVER_FLAGS_DFS_OFFLOAD);
|
||||
|
||||
if (group_id >= 0)
|
||||
return p2p_ctrl_group_add_persistent(wpa_s, group_id,
|
||||
freq, freq2, ht40, vht,
|
||||
@ -8428,7 +8447,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
||||
|
||||
#ifdef CONFIG_WPS_TESTING
|
||||
wps_version_number = 0x20;
|
||||
wps_testing_dummy_cred = 0;
|
||||
wps_testing_stub_cred = 0;
|
||||
wps_corrupt_pkhash = 0;
|
||||
wps_force_auth_types_in_use = 0;
|
||||
wps_force_encr_types_in_use = 0;
|
||||
@ -8551,6 +8570,9 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
||||
wpabuf_free(wpa_s->rsnxe_override_eapol);
|
||||
wpa_s->rsnxe_override_eapol = NULL;
|
||||
wpas_clear_driver_signal_override(wpa_s);
|
||||
wpa_s->disable_scs_support = 0;
|
||||
wpa_s->disable_mscs_support = 0;
|
||||
wpa_s->enable_dscp_policy_capa = 0;
|
||||
wpa_s->oci_freq_override_eapol = 0;
|
||||
wpa_s->oci_freq_override_saquery_req = 0;
|
||||
wpa_s->oci_freq_override_saquery_resp = 0;
|
||||
@ -10602,6 +10624,8 @@ static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
|
||||
if (sscanf(pos, "%d %d %d %d", &reauth_time, &expiration,
|
||||
&entry->akmp, &entry->opportunistic) != 4)
|
||||
goto fail;
|
||||
if (reauth_time > expiration)
|
||||
goto fail;
|
||||
for (i = 0; i < 4; i++) {
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (!pos) {
|
||||
@ -10887,6 +10911,581 @@ static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
|
||||
#endif /* CONFIG_PASN */
|
||||
|
||||
|
||||
static int set_type4_frame_classifier(const char *cmd,
|
||||
struct type4_params *param)
|
||||
{
|
||||
const char *pos, *end;
|
||||
u8 classifier_mask = 0;
|
||||
int ret;
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
size_t alen;
|
||||
|
||||
if (os_strstr(cmd, "ip_version=ipv4")) {
|
||||
param->ip_version = IPV4;
|
||||
} else if (os_strstr(cmd, "ip_version=ipv6")) {
|
||||
param->ip_version = IPV6;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "IP version missing/invalid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
classifier_mask |= BIT(0);
|
||||
|
||||
pos = os_strstr(cmd, "src_ip=");
|
||||
if (pos) {
|
||||
pos += 7;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
alen = end - pos;
|
||||
if (alen >= INET6_ADDRSTRLEN)
|
||||
return -1;
|
||||
os_memcpy(addr, pos, alen);
|
||||
addr[alen] = '\0';
|
||||
if (param->ip_version == IPV4)
|
||||
ret = inet_pton(AF_INET, addr,
|
||||
¶m->ip_params.v4.src_ip);
|
||||
else
|
||||
ret = inet_pton(AF_INET6, addr,
|
||||
¶m->ip_params.v6.src_ip);
|
||||
|
||||
if (ret != 1) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Error converting src IP address to binary ret=%d",
|
||||
ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
classifier_mask |= BIT(1);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "dst_ip=");
|
||||
if (pos) {
|
||||
pos += 7;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
alen = end - pos;
|
||||
if (alen >= INET6_ADDRSTRLEN)
|
||||
return -1;
|
||||
os_memcpy(addr, pos, alen);
|
||||
addr[alen] = '\0';
|
||||
if (param->ip_version == IPV4)
|
||||
ret = inet_pton(AF_INET, addr,
|
||||
¶m->ip_params.v4.dst_ip);
|
||||
else
|
||||
ret = inet_pton(AF_INET6, addr,
|
||||
¶m->ip_params.v6.dst_ip);
|
||||
|
||||
if (ret != 1) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Error converting dst IP address to binary ret=%d",
|
||||
ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
classifier_mask |= BIT(2);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "src_port=");
|
||||
if (pos && atoi(pos + 9) > 0) {
|
||||
if (param->ip_version == IPV4)
|
||||
param->ip_params.v4.src_port = atoi(pos + 9);
|
||||
else
|
||||
param->ip_params.v6.src_port = atoi(pos + 9);
|
||||
classifier_mask |= BIT(3);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "dst_port=");
|
||||
if (pos && atoi(pos + 9) > 0) {
|
||||
if (param->ip_version == IPV4)
|
||||
param->ip_params.v4.dst_port = atoi(pos + 9);
|
||||
else
|
||||
param->ip_params.v6.dst_port = atoi(pos + 9);
|
||||
classifier_mask |= BIT(4);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "dscp=");
|
||||
if (pos && atoi(pos + 5) > 0) {
|
||||
if (param->ip_version == IPV4)
|
||||
param->ip_params.v4.dscp = atoi(pos + 5);
|
||||
else
|
||||
param->ip_params.v6.dscp = atoi(pos + 5);
|
||||
classifier_mask |= BIT(5);
|
||||
}
|
||||
|
||||
if (param->ip_version == IPV4) {
|
||||
pos = os_strstr(cmd, "protocol=");
|
||||
if (pos) {
|
||||
if (os_strstr(pos, "udp")) {
|
||||
param->ip_params.v4.protocol = 17;
|
||||
} else if (os_strstr(pos, "tcp")) {
|
||||
param->ip_params.v4.protocol = 6;
|
||||
} else if (os_strstr(pos, "esp")) {
|
||||
param->ip_params.v4.protocol = 50;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Invalid protocol");
|
||||
return -1;
|
||||
}
|
||||
classifier_mask |= BIT(6);
|
||||
}
|
||||
} else {
|
||||
pos = os_strstr(cmd, "next_header=");
|
||||
if (pos) {
|
||||
if (os_strstr(pos, "udp")) {
|
||||
param->ip_params.v6.next_header = 17;
|
||||
} else if (os_strstr(pos, "tcp")) {
|
||||
param->ip_params.v6.next_header = 6;
|
||||
} else if (os_strstr(pos, "esp")) {
|
||||
param->ip_params.v6.next_header = 50;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Invalid next header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
classifier_mask |= BIT(6);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "flow_label=");
|
||||
if (pos) {
|
||||
pos += 11;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
if (end - pos != 6 ||
|
||||
hexstr2bin(pos, param->ip_params.v6.flow_label,
|
||||
3) ||
|
||||
param->ip_params.v6.flow_label[0] > 0x0F) {
|
||||
wpa_printf(MSG_ERROR, "Invalid flow label");
|
||||
return -1;
|
||||
}
|
||||
|
||||
classifier_mask |= BIT(7);
|
||||
}
|
||||
}
|
||||
|
||||
param->classifier_mask = classifier_mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int set_type10_frame_classifier(const char *cmd,
|
||||
struct type10_params *param)
|
||||
{
|
||||
const char *pos, *end;
|
||||
size_t filter_len;
|
||||
|
||||
pos = os_strstr(cmd, "prot_instance=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR, "Protocol instance missing");
|
||||
return -1;
|
||||
}
|
||||
param->prot_instance = atoi(pos + 14);
|
||||
|
||||
pos = os_strstr(cmd, "prot_number=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR, "Protocol number missing");
|
||||
return -1;
|
||||
}
|
||||
if (os_strstr(pos, "udp")) {
|
||||
param->prot_number = 17;
|
||||
} else if (os_strstr(pos, "tcp")) {
|
||||
param->prot_number = 6;
|
||||
} else if (os_strstr(pos, "esp")) {
|
||||
param->prot_number = 50;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Invalid protocol number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "filter_value=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Classifier parameter filter_value missing");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += 13;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
filter_len = (end - pos) / 2;
|
||||
param->filter_value = os_malloc(filter_len);
|
||||
if (!param->filter_value)
|
||||
return -1;
|
||||
|
||||
if (hexstr2bin(pos, param->filter_value, filter_len)) {
|
||||
wpa_printf(MSG_ERROR, "Invalid filter_value %s", pos);
|
||||
goto free;
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "filter_mask=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Classifier parameter filter_mask missing");
|
||||
goto free;
|
||||
}
|
||||
|
||||
pos += 12;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
if (filter_len != (size_t) (end - pos) / 2) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Filter mask length mismatch expected=%zu received=%zu",
|
||||
filter_len, (size_t) (end - pos) / 2);
|
||||
goto free;
|
||||
}
|
||||
|
||||
param->filter_mask = os_malloc(filter_len);
|
||||
if (!param->filter_mask)
|
||||
goto free;
|
||||
|
||||
if (hexstr2bin(pos, param->filter_mask, filter_len)) {
|
||||
wpa_printf(MSG_ERROR, "Invalid filter mask %s", pos);
|
||||
os_free(param->filter_mask);
|
||||
param->filter_mask = NULL;
|
||||
goto free;
|
||||
}
|
||||
|
||||
param->filter_len = filter_len;
|
||||
return 0;
|
||||
free:
|
||||
os_free(param->filter_value);
|
||||
param->filter_value = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int scs_parse_type4(struct tclas_element *elem, const char *pos)
|
||||
{
|
||||
struct type4_params type4_param = { 0 };
|
||||
|
||||
if (set_type4_frame_classifier(pos, &type4_param) == -1) {
|
||||
wpa_printf(MSG_ERROR, "Failed to set frame_classifier 4");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(&elem->frame_classifier.type4_param,
|
||||
&type4_param, sizeof(struct type4_params));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int scs_parse_type10(struct tclas_element *elem, const char *pos)
|
||||
{
|
||||
struct type10_params type10_param = { 0 };
|
||||
|
||||
if (set_type10_frame_classifier(pos, &type10_param) == -1) {
|
||||
wpa_printf(MSG_ERROR, "Failed to set frame_classifier 10");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(&elem->frame_classifier.type10_param,
|
||||
&type10_param, sizeof(struct type10_params));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
|
||||
char *cmd)
|
||||
{
|
||||
char *pos1, *pos;
|
||||
struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
|
||||
struct scs_desc_elem desc_elem = { 0 };
|
||||
int val;
|
||||
unsigned int num_scs_desc = 0;
|
||||
|
||||
if (wpa_s->ongoing_scs_req) {
|
||||
wpa_printf(MSG_ERROR, "%s: SCS Request already in queue",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* format:
|
||||
* [scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>]
|
||||
* [classifier_type=<4|10>]
|
||||
* [classifier params based on classifier type]
|
||||
* [tclas_processing=<0|1>] [scs_id=<decimal number>] ...
|
||||
*/
|
||||
pos1 = os_strstr(cmd, "scs_id=");
|
||||
if (!pos1) {
|
||||
wpa_printf(MSG_ERROR, "SCSID not present");
|
||||
return -1;
|
||||
}
|
||||
|
||||
free_up_scs_desc(scs_data);
|
||||
|
||||
while (pos1) {
|
||||
struct scs_desc_elem *n1;
|
||||
struct active_scs_elem *active_scs_desc;
|
||||
char *next_scs_desc;
|
||||
unsigned int num_tclas_elem = 0;
|
||||
bool scsid_active = false;
|
||||
|
||||
desc_elem.scs_id = atoi(pos1 + 7);
|
||||
pos1 += 7;
|
||||
|
||||
next_scs_desc = os_strstr(pos1, "scs_id=");
|
||||
if (next_scs_desc) {
|
||||
char temp[20];
|
||||
|
||||
os_snprintf(temp, sizeof(temp), "scs_id=%d ",
|
||||
desc_elem.scs_id);
|
||||
if (os_strstr(next_scs_desc, temp)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Multiple SCS descriptors configured with same SCSID(=%d)",
|
||||
desc_elem.scs_id);
|
||||
goto free_scs_desc;
|
||||
}
|
||||
pos1[next_scs_desc - pos1 - 1] = '\0';
|
||||
}
|
||||
|
||||
dl_list_for_each(active_scs_desc, &wpa_s->active_scs_ids,
|
||||
struct active_scs_elem, list) {
|
||||
if (desc_elem.scs_id == active_scs_desc->scs_id) {
|
||||
scsid_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (os_strstr(pos1, "add ")) {
|
||||
desc_elem.request_type = SCS_REQ_ADD;
|
||||
if (scsid_active) {
|
||||
wpa_printf(MSG_ERROR, "SCSID %d already active",
|
||||
desc_elem.scs_id);
|
||||
return -1;
|
||||
}
|
||||
} else if (os_strstr(pos1, "remove")) {
|
||||
desc_elem.request_type = SCS_REQ_REMOVE;
|
||||
if (!scsid_active) {
|
||||
wpa_printf(MSG_ERROR, "SCSID %d not active",
|
||||
desc_elem.scs_id);
|
||||
return -1;
|
||||
}
|
||||
goto scs_desc_end;
|
||||
} else if (os_strstr(pos1, "change ")) {
|
||||
desc_elem.request_type = SCS_REQ_CHANGE;
|
||||
if (!scsid_active) {
|
||||
wpa_printf(MSG_ERROR, "SCSID %d not active",
|
||||
desc_elem.scs_id);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "SCS Request type invalid");
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
pos1 = os_strstr(pos1, "scs_up=");
|
||||
if (!pos1) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Intra-Access user priority not present");
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
val = atoi(pos1 + 7);
|
||||
if (val < 0 || val > 7) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Intra-Access user priority invalid %d",
|
||||
val);
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
desc_elem.intra_access_priority = val;
|
||||
desc_elem.scs_up_avail = true;
|
||||
|
||||
pos = os_strstr(pos1, "classifier_type=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR, "classifier type empty");
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
while (pos) {
|
||||
struct tclas_element elem = { 0 }, *n;
|
||||
char *next_tclas_elem;
|
||||
|
||||
val = atoi(pos + 16);
|
||||
if (val != 4 && val != 10) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"classifier type invalid %d", val);
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
elem.classifier_type = val;
|
||||
pos += 16;
|
||||
|
||||
next_tclas_elem = os_strstr(pos, "classifier_type=");
|
||||
if (next_tclas_elem) {
|
||||
pos1 = next_tclas_elem;
|
||||
pos[next_tclas_elem - pos - 1] = '\0';
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case 4:
|
||||
if (scs_parse_type4(&elem, pos) < 0)
|
||||
goto free_scs_desc;
|
||||
break;
|
||||
case 10:
|
||||
if (scs_parse_type10(&elem, pos) < 0)
|
||||
goto free_scs_desc;
|
||||
break;
|
||||
}
|
||||
|
||||
n = os_realloc(desc_elem.tclas_elems,
|
||||
(num_tclas_elem + 1) * sizeof(elem));
|
||||
if (!n)
|
||||
goto free_scs_desc;
|
||||
|
||||
desc_elem.tclas_elems = n;
|
||||
os_memcpy((u8 *) desc_elem.tclas_elems +
|
||||
num_tclas_elem * sizeof(elem),
|
||||
&elem, sizeof(elem));
|
||||
num_tclas_elem++;
|
||||
desc_elem.num_tclas_elem = num_tclas_elem;
|
||||
pos = next_tclas_elem;
|
||||
}
|
||||
|
||||
if (desc_elem.num_tclas_elem > 1) {
|
||||
pos1 = os_strstr(pos1, "tclas_processing=");
|
||||
if (!pos1) {
|
||||
wpa_printf(MSG_ERROR, "tclas_processing empty");
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
val = atoi(pos1 + 17);
|
||||
if (val != 0 && val != 1) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"tclas_processing invalid");
|
||||
goto free_scs_desc;
|
||||
}
|
||||
|
||||
desc_elem.tclas_processing = val;
|
||||
}
|
||||
|
||||
scs_desc_end:
|
||||
n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
|
||||
sizeof(struct scs_desc_elem));
|
||||
if (!n1)
|
||||
goto free_scs_desc;
|
||||
|
||||
scs_data->scs_desc_elems = n1;
|
||||
os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_desc *
|
||||
sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
|
||||
num_scs_desc++;
|
||||
scs_data->num_scs_desc = num_scs_desc;
|
||||
pos1 = next_scs_desc;
|
||||
os_memset(&desc_elem, 0, sizeof(desc_elem));
|
||||
}
|
||||
|
||||
return wpas_send_scs_req(wpa_s);
|
||||
|
||||
free_scs_desc:
|
||||
free_up_tclas_elem(&desc_elem);
|
||||
free_up_scs_desc(scs_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int wpas_ctrl_iface_send_dscp_resp(struct wpa_supplicant *wpa_s,
|
||||
const char *cmd)
|
||||
{
|
||||
char *pos;
|
||||
struct dscp_policy_status *policy = NULL, *n;
|
||||
int num_policies = 0, ret = -1;
|
||||
struct dscp_resp_data resp_data;
|
||||
|
||||
/*
|
||||
* format:
|
||||
* <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
|
||||
*/
|
||||
|
||||
os_memset(&resp_data, 0, sizeof(resp_data));
|
||||
|
||||
resp_data.more = os_strstr(cmd, "more") != NULL;
|
||||
|
||||
if (os_strstr(cmd, "reset")) {
|
||||
resp_data.reset = true;
|
||||
resp_data.solicited = false;
|
||||
goto send_resp;
|
||||
}
|
||||
|
||||
resp_data.solicited = os_strstr(cmd, "solicited") != NULL;
|
||||
|
||||
pos = os_strstr(cmd, "policy_id=");
|
||||
while (pos) {
|
||||
n = os_realloc(policy, (num_policies + 1) * sizeof(*policy));
|
||||
if (!n)
|
||||
goto fail;
|
||||
|
||||
policy = n;
|
||||
pos += 10;
|
||||
policy[num_policies].id = atoi(pos);
|
||||
if (policy[num_policies].id == 0) {
|
||||
wpa_printf(MSG_ERROR, "DSCP: Invalid policy id");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pos = os_strstr(pos, "status=");
|
||||
if (!pos) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"DSCP: Status is not found for a policy");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pos += 7;
|
||||
policy[num_policies].status = atoi(pos);
|
||||
num_policies++;
|
||||
|
||||
pos = os_strstr(pos, "policy_id");
|
||||
}
|
||||
|
||||
resp_data.policy = policy;
|
||||
resp_data.num_policies = num_policies;
|
||||
send_resp:
|
||||
ret = wpas_send_dscp_response(wpa_s, &resp_data);
|
||||
if (ret)
|
||||
wpa_printf(MSG_ERROR, "DSCP: Failed to send DSCP response");
|
||||
fail:
|
||||
os_free(policy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int wpas_ctrl_iface_send_dscp_query(struct wpa_supplicant *wpa_s,
|
||||
const char *cmd)
|
||||
{
|
||||
char *pos;
|
||||
|
||||
/*
|
||||
* format:
|
||||
* Wildcard DSCP query
|
||||
* <wildcard>
|
||||
*
|
||||
* DSCP query with a domain name attribute:
|
||||
* [domain_name=<string>]
|
||||
*/
|
||||
|
||||
if (os_strstr(cmd, "wildcard")) {
|
||||
wpa_printf(MSG_DEBUG, "QM: Send wildcard DSCP policy query");
|
||||
return wpas_send_dscp_query(wpa_s, NULL, 0);
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "domain_name=");
|
||||
if (!pos || !os_strlen(pos + 12)) {
|
||||
wpa_printf(MSG_ERROR, "QM: Domain name not preset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return wpas_send_dscp_query(wpa_s, pos + 12, os_strlen(pos + 12));
|
||||
}
|
||||
|
||||
|
||||
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||
char *buf, size_t *resp_len)
|
||||
{
|
||||
@ -11458,6 +12057,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||
} else if (os_strcmp(buf, "STOP_AP") == 0) {
|
||||
if (wpas_ap_stop_ap(wpa_s))
|
||||
reply_len = -1;
|
||||
} else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
|
||||
if (wpas_ap_update_beacon(wpa_s))
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_AP */
|
||||
} else if (os_strcmp(buf, "SUSPEND") == 0) {
|
||||
wpas_notify_suspend(wpa_s->global);
|
||||
@ -11812,6 +12414,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||
if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_PASN */
|
||||
} else if (os_strncmp(buf, "SCS ", 4) == 0) {
|
||||
if (wpas_ctrl_iface_configure_scs(wpa_s, buf + 4))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "DSCP_RESP ", 10) == 0) {
|
||||
if (wpas_ctrl_iface_send_dscp_resp(wpa_s, buf + 10))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "DSCP_QUERY ", 11) == 0) {
|
||||
if (wpas_ctrl_iface_send_dscp_query(wpa_s, buf + 11))
|
||||
reply_len = -1;
|
||||
} else {
|
||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||
reply_len = 16;
|
||||
|
@ -46,7 +46,7 @@
|
||||
can be used to improve the network security, but even that has inherited
|
||||
security issues due to the use of WEP for encryption. Wi-Fi Protected
|
||||
Access and IEEE 802.11i amendment to the wireless LAN standard introduce
|
||||
a much improvement mechanism for securing wireless networks. IEEE 802.11i
|
||||
a much improved mechanism for securing wireless networks. IEEE 802.11i
|
||||
enabled networks that are using CCMP (encryption mechanism based on strong
|
||||
cryptographic algorithm AES) can finally be called secure used for
|
||||
applications which require efficient protection against unauthorized
|
||||
|
@ -72,7 +72,7 @@ def wait_event(self, events, timeout=10):
|
||||
break
|
||||
return None
|
||||
|
||||
def run(ifname, count, no_fast_reauth, res):
|
||||
def run(ifname, count, no_fast_reauth, res, conf):
|
||||
et = eapol_test(ifname)
|
||||
|
||||
et.request("AP_SCAN 0")
|
||||
@ -81,14 +81,20 @@ def run(ifname, count, no_fast_reauth, res):
|
||||
else:
|
||||
et.request("SET fast_reauth 1")
|
||||
id = et.add_network()
|
||||
et.set_network(id, "key_mgmt", "IEEE8021X")
|
||||
et.set_network(id, "eapol_flags", "0")
|
||||
et.set_network(id, "eap", "TLS")
|
||||
et.set_network_quoted(id, "identity", "user")
|
||||
et.set_network_quoted(id, "ca_cert", 'ca.pem')
|
||||
et.set_network_quoted(id, "client_cert", 'client.pem')
|
||||
et.set_network_quoted(id, "private_key", 'client.key')
|
||||
et.set_network_quoted(id, "private_key_passwd", 'whatever')
|
||||
|
||||
if len(conf):
|
||||
for item in conf:
|
||||
et.set_network(id, item, conf[item])
|
||||
else:
|
||||
et.set_network(id, "key_mgmt", "IEEE8021X")
|
||||
et.set_network(id, "eapol_flags", "0")
|
||||
et.set_network(id, "eap", "TLS")
|
||||
et.set_network_quoted(id, "identity", "user")
|
||||
et.set_network_quoted(id, "ca_cert", 'ca.pem')
|
||||
et.set_network_quoted(id, "client_cert", 'client.pem')
|
||||
et.set_network_quoted(id, "private_key", 'client.key')
|
||||
et.set_network_quoted(id, "private_key_passwd", 'whatever')
|
||||
|
||||
et.set_network(id, "disabled", "0")
|
||||
|
||||
fail = False
|
||||
@ -114,6 +120,7 @@ def main():
|
||||
parser.add_argument('--no-fast-reauth', action='store_true',
|
||||
dest='no_fast_reauth',
|
||||
help='disable TLS session resumption')
|
||||
parser.add_argument('--conf', help='file of network conf items')
|
||||
args = parser.parse_args()
|
||||
|
||||
num = int(args.num)
|
||||
@ -122,12 +129,22 @@ def main():
|
||||
global wpas_ctrl
|
||||
wpas_ctrl = args.ctrl
|
||||
|
||||
conf = {}
|
||||
if args.conf:
|
||||
f = open(args.conf, "r")
|
||||
for line in f:
|
||||
confitem = line.split("=")
|
||||
if len(confitem) == 2:
|
||||
conf[confitem[0].strip()] = confitem[1].strip()
|
||||
f.close()
|
||||
|
||||
t = {}
|
||||
res = {}
|
||||
for i in range(num):
|
||||
res[i] = Queue.Queue()
|
||||
t[i] = threading.Thread(target=run, args=(str(i), iter,
|
||||
args.no_fast_reauth, res[i]))
|
||||
args.no_fast_reauth, res[i],
|
||||
conf))
|
||||
for i in range(num):
|
||||
t[i].start()
|
||||
for i in range(num):
|
||||
|
@ -356,9 +356,14 @@ static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
|
||||
struct wpa_ie_data ie;
|
||||
int pmksa_set = -1;
|
||||
size_t i;
|
||||
struct rsn_pmksa_cache_entry *cur_pmksa;
|
||||
|
||||
/* Start with assumption of no PMKSA cache entry match */
|
||||
pmksa_cache_clear_current(wpa_s->wpa);
|
||||
/* Start with assumption of no PMKSA cache entry match for cases other
|
||||
* than SAE. In particular, this is needed to generate the PMKSA cache
|
||||
* entries for Suite B cases with driver-based roaming indication. */
|
||||
cur_pmksa = pmksa_cache_get_current(wpa_s->wpa);
|
||||
if (cur_pmksa && !wpa_key_mgmt_sae(cur_pmksa->akmp))
|
||||
pmksa_cache_clear_current(wpa_s->wpa);
|
||||
|
||||
if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
|
||||
ie.pmkid == NULL)
|
||||
@ -2680,6 +2685,205 @@ static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
|
||||
static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
int sel;
|
||||
const u8 *p;
|
||||
int l, len;
|
||||
bool found = false;
|
||||
struct wpa_ie_data ie;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
struct wpa_bss *bss = wpa_s->current_bss;
|
||||
int pmf;
|
||||
|
||||
if (!ssid)
|
||||
return 0;
|
||||
|
||||
p = data->assoc_info.req_ies;
|
||||
l = data->assoc_info.req_ies_len;
|
||||
|
||||
while (p && l >= 2) {
|
||||
len = p[1] + 2;
|
||||
if (len > l) {
|
||||
wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
|
||||
p, l);
|
||||
break;
|
||||
}
|
||||
if (((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
|
||||
(os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
|
||||
(p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
|
||||
(os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
|
||||
(p[0] == WLAN_EID_RSN && p[1] >= 2))) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
l -= len;
|
||||
p += len;
|
||||
}
|
||||
|
||||
if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
|
||||
return 0;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG,
|
||||
"WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq",
|
||||
p, l);
|
||||
|
||||
/* Update proto from (Re)Association Request frame info */
|
||||
wpa_s->wpa_proto = ie.proto;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto);
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
|
||||
!!(wpa_s->wpa_proto &
|
||||
(WPA_PROTO_RSN | WPA_PROTO_OSEN)));
|
||||
|
||||
/* Update AKMP suite from (Re)Association Request frame info */
|
||||
sel = ie.key_mgmt;
|
||||
if (ssid->key_mgmt)
|
||||
sel &= ssid->key_mgmt;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: AP key_mgmt 0x%x network key_mgmt 0x%x; available key_mgmt 0x%x",
|
||||
ie.key_mgmt, ssid->key_mgmt, sel);
|
||||
if (ie.key_mgmt && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_AKMP_NOT_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->key_mgmt = ie.key_mgmt;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d",
|
||||
wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto),
|
||||
wpa_s->wpa_proto);
|
||||
|
||||
/* Update pairwise cipher from (Re)Association Request frame info */
|
||||
sel = ie.pairwise_cipher;
|
||||
if (ssid->pairwise_cipher)
|
||||
sel &= ssid->pairwise_cipher;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x",
|
||||
ie.pairwise_cipher, ssid->pairwise_cipher, sel);
|
||||
if (ie.pairwise_cipher && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->pairwise_cipher = ie.pairwise_cipher;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
|
||||
wpa_s->pairwise_cipher);
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
|
||||
wpa_cipher_txt(wpa_s->pairwise_cipher));
|
||||
|
||||
/* Update other parameters based on AP's WPA IE/RSNE, if available */
|
||||
if (!bss) {
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: current_bss == NULL - skip AP IE check");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update GTK and IGTK from AP's RSNE */
|
||||
found = false;
|
||||
|
||||
if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
|
||||
const u8 *bss_rsn;
|
||||
|
||||
bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
|
||||
if (bss_rsn) {
|
||||
p = bss_rsn;
|
||||
len = 2 + bss_rsn[1];
|
||||
found = true;
|
||||
}
|
||||
} else if (wpa_s->wpa_proto & WPA_PROTO_WPA) {
|
||||
const u8 *bss_wpa;
|
||||
|
||||
bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
|
||||
if (bss_wpa) {
|
||||
p = bss_wpa;
|
||||
len = 2 + bss_wpa[1];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
|
||||
return 0;
|
||||
|
||||
pmf = wpas_get_ssid_pmf(wpa_s, ssid);
|
||||
if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
|
||||
pmf == MGMT_FRAME_PROTECTION_REQUIRED) {
|
||||
/* AP does not support MFP, local configuration requires it */
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
|
||||
return -1;
|
||||
}
|
||||
if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
|
||||
pmf == NO_MGMT_FRAME_PROTECTION) {
|
||||
/* AP requires MFP, local configuration disables it */
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update PMF from local configuration now that MFP validation was done
|
||||
* above */
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf);
|
||||
|
||||
/* Update GTK from AP's RSNE */
|
||||
sel = ie.group_cipher;
|
||||
if (ssid->group_cipher)
|
||||
sel &= ssid->group_cipher;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x",
|
||||
ie.group_cipher, ssid->group_cipher, sel);
|
||||
if (ie.group_cipher && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->group_cipher = ie.group_cipher;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
|
||||
wpa_cipher_txt(wpa_s->group_cipher));
|
||||
|
||||
/* Update IGTK from AP RSN IE */
|
||||
sel = ie.mgmt_group_cipher;
|
||||
if (ssid->group_mgmt_cipher)
|
||||
sel &= ssid->group_mgmt_cipher;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
|
||||
ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
|
||||
|
||||
if (pmf == NO_MGMT_FRAME_PROTECTION ||
|
||||
!(ie.capabilities & WPA_CAPABILITY_MFPC)) {
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x",
|
||||
ie.capabilities);
|
||||
ie.mgmt_group_cipher = 0;
|
||||
}
|
||||
|
||||
if (ie.mgmt_group_cipher && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
|
||||
wpa_s->mgmt_group_cipher);
|
||||
if (wpa_s->mgmt_group_cipher)
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s",
|
||||
wpa_cipher_txt(wpa_s->mgmt_group_cipher));
|
||||
else
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
@ -2977,6 +3181,9 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
||||
|
||||
wpa_s->assoc_freq = data->assoc_info.freq;
|
||||
|
||||
wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3121,6 +3328,10 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
|
||||
data && wpa_supplicant_use_own_rsne_params(wpa_s, data) < 0)
|
||||
return;
|
||||
|
||||
multi_ap_set_4addr_mode(wpa_s);
|
||||
|
||||
if (wpa_s->conf->ap_scan == 1 &&
|
||||
@ -4259,6 +4470,13 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
|
||||
}
|
||||
#endif /* CONFIG_DPP */
|
||||
|
||||
if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
|
||||
payload[0] == ROBUST_AV_SCS_RESP) {
|
||||
wpas_handle_robust_av_scs_recv_action(wpa_s, mgmt->sa,
|
||||
payload + 1, plen - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
|
||||
payload[0] == ROBUST_AV_MSCS_RESP) {
|
||||
wpas_handle_robust_av_recv_action(wpa_s, mgmt->sa,
|
||||
@ -4266,6 +4484,13 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
|
||||
return;
|
||||
}
|
||||
|
||||
if (category == WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED && plen > 4 &&
|
||||
WPA_GET_BE32(payload) == QM_ACTION_VENDOR_TYPE) {
|
||||
wpas_handle_qos_mgmt_recv_action(wpa_s, mgmt->sa,
|
||||
payload + 4, plen - 4);
|
||||
return;
|
||||
}
|
||||
|
||||
wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
|
||||
category, payload, plen, freq);
|
||||
if (wpa_s->ifmsh)
|
||||
@ -5238,13 +5463,21 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||
break;
|
||||
case EVENT_INTERFACE_MAC_CHANGED:
|
||||
wpa_supplicant_update_mac_addr(wpa_s);
|
||||
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
|
||||
break;
|
||||
case EVENT_INTERFACE_ENABLED:
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
|
||||
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
|
||||
u8 addr[ETH_ALEN];
|
||||
|
||||
eloop_cancel_timeout(wpas_clear_disabled_interface,
|
||||
wpa_s, NULL);
|
||||
os_memcpy(addr, wpa_s->own_addr, ETH_ALEN);
|
||||
wpa_supplicant_update_mac_addr(wpa_s);
|
||||
if (os_memcmp(addr, wpa_s->own_addr, ETH_ALEN) != 0)
|
||||
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
|
||||
else
|
||||
wpa_sm_pmksa_cache_reconfig(wpa_s->wpa);
|
||||
wpa_supplicant_set_default_scan_ies(wpa_s);
|
||||
if (wpa_s->p2p_mgmt) {
|
||||
wpa_supplicant_set_state(wpa_s,
|
||||
|
@ -273,16 +273,6 @@ static void gas_query_tx_status(struct wpa_supplicant *wpa_s,
|
||||
}
|
||||
|
||||
|
||||
int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr)
|
||||
{
|
||||
if (wpa_s->current_ssid == NULL ||
|
||||
wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
|
||||
os_memcmp(addr, wpa_s->bssid, ETH_ALEN) != 0)
|
||||
return 0;
|
||||
return wpa_sm_pmf_enabled(wpa_s->wpa);
|
||||
}
|
||||
|
||||
|
||||
static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
|
||||
struct wpabuf *req, unsigned int wait_time)
|
||||
{
|
||||
|
@ -19,7 +19,6 @@ void gas_query_deinit(struct gas_query *gas);
|
||||
int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
|
||||
const u8 *bssid, u8 categ, const u8 *data, size_t len,
|
||||
int freq);
|
||||
int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
|
||||
|
||||
/**
|
||||
* enum gas_query_result - GAS query result
|
||||
|
@ -437,6 +437,37 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
||||
if (!conf)
|
||||
goto out_free;
|
||||
|
||||
if (is_6ghz_freq(freq->freq)) {
|
||||
/*
|
||||
* IEEE Std 802.11ax-2021, 12.12.2:
|
||||
* The STA shall use management frame protection (MFPR=1) when
|
||||
* using RSN.
|
||||
*/
|
||||
ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
|
||||
|
||||
/* Set mandatory op_class parameter for setting up BSS */
|
||||
switch (freq->bandwidth) {
|
||||
case 20:
|
||||
if (freq->freq == 5935)
|
||||
conf->op_class = 136;
|
||||
else
|
||||
conf->op_class = 131;
|
||||
break;
|
||||
case 40:
|
||||
conf->op_class = 132;
|
||||
break;
|
||||
case 80:
|
||||
conf->op_class = 133;
|
||||
break;
|
||||
case 160:
|
||||
conf->op_class = 134;
|
||||
break;
|
||||
default:
|
||||
conf->op_class = 131;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bss->conf = *conf->bss;
|
||||
bss->conf->start_disabled = 1;
|
||||
bss->conf->mesh = MESH_ENABLED;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user