Merge "P2P: fix typo"
diff --git a/OWNERS b/OWNERS
index cd9dfa9..351212a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,2 @@
etancohen@google.com
-haishalom@google.com
arabawy@google.com
diff --git a/hostapd/Android.bp b/hostapd/Android.bp
index 2a25208..020396d 100644
--- a/hostapd/Android.bp
+++ b/hostapd/Android.bp
@@ -169,6 +169,35 @@
"-Wno-unused-variable",
"-Wno-macro-redefined",
],
+ // Similar to suppressing clang compiler warnings, here we
+ // suppress clang-tidy warnings to reduce noises in Android build.log.
+ tidy_checks: [
+ "-android-cloexec-*",
+ "-bugprone-branch-clone",
+ "-bugprone-macro-parentheses",
+ "-bugprone-misplaced-widening-cast",
+ "-bugprone-signal-handler",
+ "-bugprone-signed-char-misuse",
+ "-bugprone-sizeof-expression",
+ "-bugprone-suspicious-string-compare",
+ "-bugprone-too-small-loop-variable",
+ "-cert-err34-c",
+ "-cert-msc30-c",
+ "-cert-msc50-cpp",
+ "-cert-msc54-cpp",
+ "-cert-sig30-c",
+ "-cert-str34-c",
+ "-clang-analyzer-core.NullDereference",
+ "-clang-analyzer-core.UndefinedBinaryOperatorResult",
+ "-clang-analyzer-deadcode.DeadStores",
+ "-clang-analyzer-optin.performance.Padding",
+ "-clang-analyzer-optin.portability.UnixAPI",
+ "-clang-analyzer-security.insecureAPI.UncheckedReturn",
+ "-clang-analyzer-unix.cstring.NullArg",
+ "-clang-analyzer-unix.Malloc",
+ "-clang-diagnostic-unused-but-set-variable",
+ "-misc-redundant-expression",
+ ],
}
@@ -318,3 +347,9 @@
],
}
+
+// This manifest can used by a vendor apex module for hostapd as well.
+filegroup {
+ name: "android.hardware.wifi.hostapd.xml",
+ srcs: ["android.hardware.wifi.hostapd.xml"],
+}
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index f2200d6..35bfbe7 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -702,6 +702,9 @@
const std::vector<uint8_t>& client_address,
const uint16_t reason_code) {
struct sta_info *sta;
+ if (client_address.size() != ETH_ALEN) {
+ return false;
+ }
for (sta = hapd->sta_list; sta; sta = sta->next) {
int res;
res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
diff --git a/src/common/dpp.h b/src/common/dpp.h
index ee29a08..3094be8 100644
--- a/src/common/dpp.h
+++ b/src/common/dpp.h
@@ -296,6 +296,7 @@
enum dpp_status_error auth_resp_status;
enum dpp_status_error conf_resp_status;
enum dpp_status_error force_conf_resp_status;
+ enum dpp_status_error conn_result_status;
u8 peer_mac_addr[ETH_ALEN];
u8 i_nonce[DPP_MAX_NONCE_LEN];
u8 r_nonce[DPP_MAX_NONCE_LEN];
@@ -340,6 +341,7 @@
int connect_on_tx_status;
int waiting_conf_result;
int waiting_conn_status_result;
+ int tx_conn_status_result_started;
int auth_success;
bool reconfig_success;
struct wpabuf *conf_req;
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 52dc8df..d6fd792 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -312,10 +312,14 @@
elems->pasn_params_len = elen;
break;
case WLAN_EID_EXT_EHT_CAPABILITIES:
+ if (elen < EHT_CAPABILITIES_IE_MIN_LEN)
+ break;
elems->eht_capabilities = pos;
elems->eht_capabilities_len = elen;
break;
case WLAN_EID_EXT_EHT_OPERATION:
+ if (elen < EHT_OPERATION_IE_MIN_LEN)
+ break;
elems->eht_operation = pos;
elems->eht_operation_len = elen;
break;
@@ -2851,6 +2855,7 @@
struct supported_chan_width supported_width;
supported_width.is_160_supported = 0;
supported_width.is_80p80_supported = 0;
+ supported_width.is_320_supported = 0;
if (elems == NULL)
return supported_width;
@@ -2858,6 +2863,8 @@
(struct ieee80211_vht_capabilities *) elems->vht_capabilities;
struct ieee80211_he_capabilities *hecaps =
(struct ieee80211_he_capabilities *) elems->he_capabilities;
+ struct ieee80211_eht_capabilities *ehtcaps =
+ (struct ieee80211_eht_capabilities *) elems->eht_capabilities;
if (vhtcaps) {
le32 vht_capabilities_info =
@@ -2875,8 +2882,16 @@
if (channel_width_set & HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)
supported_width.is_80p80_supported = 1;
}
- wpa_printf(MSG_DEBUG, " IE indicate 160 supported: %u, 80+80 supported: %u",
- supported_width.is_160_supported, supported_width.is_80p80_supported);
+ if (ehtcaps) {
+ if (ehtcaps->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &
+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)
+ supported_width.is_320_supported = 1;
+ }
+ wpa_printf(MSG_DEBUG,
+ " IE indicates 320 supported: %u, 160 supported: %u, 80+80 supported: %u",
+ supported_width.is_320_supported,
+ supported_width.is_160_supported,
+ supported_width.is_80p80_supported);
return supported_width;
}
@@ -2986,6 +3001,39 @@
return channel_width;
}
+/* Parse EHT operation IE to get EHT operation channel width */
+static enum chan_width get_eht_operation_channel_width(
+ struct ieee80211_eht_operation *eht_oper,
+ int eht_oper_len)
+{
+ enum chan_width channel_width = CHAN_WIDTH_UNKNOWN;
+ if (!(eht_oper->oper_params & EHT_OPER_INFO_PRESENT) ||
+ eht_oper_len < (EHT_OPERATION_IE_MIN_LEN + EHT_OPER_INFO_MIN_LEN))
+ return channel_width;
+
+ switch (eht_oper->oper_info.control & EHT_OPER_CHANNEL_WIDTH_MASK) {
+ case EHT_OPER_CHANNEL_WIDTH_20MHZ:
+ channel_width = CHAN_WIDTH_20;
+ break;
+ case EHT_OPER_CHANNEL_WIDTH_40MHZ:
+ channel_width = CHAN_WIDTH_40;
+ break;
+ case EHT_OPER_CHANNEL_WIDTH_80MHZ:
+ channel_width = CHAN_WIDTH_80;
+ break;
+ case EHT_OPER_CHANNEL_WIDTH_160MHZ:
+ channel_width = CHAN_WIDTH_160;
+ break;
+ case EHT_OPER_CHANNEL_WIDTH_320MHZ:
+ channel_width = CHAN_WIDTH_320;
+ break;
+ default:
+ break;
+ }
+ wpa_printf(MSG_DEBUG, " EHT operation CBW: %u", channel_width);
+ return channel_width;
+}
+
/* Parse HT/VHT/HE operation IEs to get operation channel width */
enum chan_width get_operation_channel_width(struct ieee802_11_elems *elems)
{
@@ -2999,7 +3047,14 @@
(struct ieee80211_vht_operation_info *) elems->vht_operation;
struct ieee80211_he_operation *he_oper =
(struct ieee80211_he_operation *) elems->he_operation;
- if (he_oper)
+ struct ieee80211_eht_operation *eht_oper =
+ (struct ieee80211_eht_operation *) elems->eht_operation;
+
+ if (eht_oper)
+ channel_width = get_eht_operation_channel_width(
+ eht_oper, elems->eht_operation_len);
+
+ if (channel_width == CHAN_WIDTH_UNKNOWN && he_oper)
channel_width = get_he_operation_channel_width(
he_oper, elems->he_operation_len);
@@ -3023,7 +3078,11 @@
enum chan_width ap_operation_chan_width,
struct supported_chan_width sta_supported_chan_width)
{
- if (ap_operation_chan_width == CHAN_WIDTH_160)
+ if (ap_operation_chan_width == CHAN_WIDTH_320 &&
+ sta_supported_chan_width.is_320_supported)
+ return CHAN_WIDTH_320;
+ if (ap_operation_chan_width == CHAN_WIDTH_160 ||
+ ap_operation_chan_width == CHAN_WIDTH_320)
return (sta_supported_chan_width.is_160_supported)
? CHAN_WIDTH_160 : CHAN_WIDTH_80;
if (ap_operation_chan_width == CHAN_WIDTH_80P80)
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 2e81751..ff31e8d 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -351,6 +351,7 @@
struct supported_chan_width {
u8 is_160_supported;
u8 is_80p80_supported;
+ u8 is_320_supported;
};
struct supported_chan_width get_supported_channel_width(struct ieee802_11_elems *elems);
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 4345488..ec3b42b 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2446,11 +2446,14 @@
/* IEEE P802.11be/D1.5, 9.4.2.311 - EHT Operation element */
+#define EHT_OPERATION_IE_MIN_LEN 1
+
/* Figure 9-1002b: EHT Operation Parameters field subfields */
#define EHT_OPER_INFO_PRESENT BIT(0)
#define EHT_OPER_DISABLED_SUBCHAN_BITMAP_PRESENT BIT(1)
/* Control subfield: Channel Width subfield; see Table 9-401b */
+#define EHT_OPER_CHANNEL_WIDTH_MASK 0x7
#define EHT_OPER_CHANNEL_WIDTH_20MHZ 0
#define EHT_OPER_CHANNEL_WIDTH_40MHZ 1
#define EHT_OPER_CHANNEL_WIDTH_80MHZ 2
@@ -2458,6 +2461,8 @@
#define EHT_OPER_CHANNEL_WIDTH_320MHZ 4
/* Figure 9-1002c: EHT Operation Information field format */
+#define EHT_OPER_INFO_MIN_LEN 3
+
struct ieee80211_eht_oper_info {
u8 control; /* B0..B2: Channel Width */
u8 ccfs0;
@@ -2473,6 +2478,8 @@
/* IEEE P802.11be/D1.5, 9.4.2.313 - EHT Capabilities element */
+#define EHT_CAPABILITIES_IE_MIN_LEN 11
+
/* Figure 9-1002af: EHT MAC Capabilities Information field */
#define EHT_MACCAP_EPCS_PRIO BIT(0)
#define EHT_MACCAP_OM_CONTROL BIT(1)
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 6bbf1ec..a546984 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2393,6 +2393,7 @@
int avg_beacon_signal;
int current_noise;
int current_txrate;
+ int current_rxrate;
enum chan_width chanwidth;
int center_frq1;
int center_frq2;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 1385edb..7472987 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1701,6 +1701,20 @@
}
}
+ if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
+ if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
+ sinfo[NL80211_STA_INFO_RX_BITRATE],
+ rate_policy)) {
+ sig_change->current_rxrate = 0;
+ } else {
+ if (rinfo[NL80211_RATE_INFO_BITRATE]) {
+ sig_change->current_rxrate =
+ nla_get_u16(rinfo[
+ NL80211_RATE_INFO_BITRATE]) * 100;
+ }
+ }
+ }
+
return NL_SKIP;
}
@@ -1712,6 +1726,7 @@
sig->current_signal = -WPA_INVALID_NOISE;
sig->current_txrate = 0;
+ sig->current_rxrate = 0;
if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) {
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 46592b3..a211d2a 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1197,7 +1197,11 @@
drv->capa.flags |= WPA_DRIVER_FLAGS_UPDATE_FT_IES;
if (!drv->capa.max_num_akms)
+#ifdef CONFIG_DRIVER_NL80211_BRCM
drv->capa.max_num_akms = 1;
+#else
+ drv->capa.max_num_akms = NL80211_MAX_NR_AKM_SUITES;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
return 0;
}
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index db46d95..a7dee37 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1731,6 +1731,9 @@
wpa_hexdump_ascii(MSG_DEBUG,
"EAP: using IMSI privacy anonymous identity",
identity, identity_len);
+ } else if (config->strict_conservative_peer_mode) {
+ wpa_printf(MSG_DEBUG, "EAP: never use real identity in conservative peer mode.");
+ return NULL;
} else {
identity = config->identity;
identity_len = config->identity_len;
@@ -2816,6 +2819,24 @@
return config->identity;
}
+
+/**
+ * eap_get_config_strict_conservative_peer_mode - get the value of
+ * strict conservative peer mode in eap_peer_config.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm)
+{
+ struct eap_peer_config *config;
+ config = eap_get_config(sm);
+ if (config) {
+ return config->strict_conservative_peer_mode;
+ }
+
+ return 0;
+}
+
+
static const u8 * strnchr(const u8 *str, size_t len, u8 needle) {
const u8 *cur = str;
@@ -3080,6 +3101,19 @@
return sm ? sm->eapKeyAvailable : 0;
}
+/**
+ * eap_notify_permanent_id_req_denied - Notify that the AT_PERMANENT_ID_REQ
+ * is denied from eap_peer when the strict conservative mode is enabled.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+void eap_notify_permanent_id_req_denied(struct eap_sm *sm)
+{
+ if (!sm || !sm->eapol_cb->notify_permanent_id_req_denied)
+ return;
+
+ sm->eapol_cb->notify_permanent_id_req_denied(sm->eapol_ctx);
+}
+
/**
* eap_notify_success - Notify EAP state machine about external success trigger
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index aae1a41..8f83d0b 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -233,6 +233,15 @@
const char *cert_hash);
/**
+ * notify_permanent_id_req_denied - Notify that the
+ * AT_PERMANENT_ID_REQ from the server was denied. This
+ * notification happens when the peer is in strict
+ * conservative mode.
+ * @ctx: eapol_ctx from eap_peer_sm_init() call
+ */
+ void (*notify_permanent_id_req_denied)(void* ctx);
+
+ /**
* notify_status - Notification of the current EAP state
* @ctx: eapol_ctx from eap_peer_sm_init() call
* @status: Step in the process of EAP authentication
@@ -366,11 +375,13 @@
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
void eap_set_external_sim(struct eap_sm *sm, int external_sim);
int eap_key_available(struct eap_sm *sm);
+void eap_notify_permanent_id_req_denied(struct eap_sm *sm);
void eap_notify_success(struct eap_sm *sm);
void eap_notify_lower_layer_success(struct eap_sm *sm);
const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len);
const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
struct wpabuf * eap_get_eapRespData(struct eap_sm *sm);
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm);
void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
void eap_invalidate_cached_session(struct eap_sm *sm);
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 7f660e6..49338cf 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -708,6 +708,12 @@
identity_len = data->pseudonym_len;
eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO, "EAP-AKA: permanent_id_req is denied in "
+ "the strict conservative peer mode");
+ eap_notify_permanent_id_req_denied(sm);
+ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 26744ab..59fac90 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -338,6 +338,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in conservative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never sends the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* machine_identity - EAP Identity for machine credential
*
* This field is used to set the machine identity or NAI for cases where
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 71e9108..6f18ebf 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -576,6 +576,12 @@
identity_len = data->pseudonym_len;
eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO, "EAP-SIM: permanent_id_req is denied in "
+ "the strict conservative peer mode");
+ eap_notify_permanent_id_req_denied(sm);
+ return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index 6173960..a0bc6ab 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -2031,6 +2031,13 @@
sm->ctx->cert_cb(sm->ctx->ctx, cert, cert_hash);
}
+static void eapol_sm_notify_permanent_id_req_denied(void *ctx)
+{
+ struct eapol_sm *sm = ctx;
+ if (sm->ctx->permanent_id_req_denied_cb)
+ sm->ctx->permanent_id_req_denied_cb(sm->ctx->ctx);
+}
+
static void eapol_sm_notify_status(void *ctx, const char *status,
const char *parameter)
@@ -2118,6 +2125,7 @@
eapol_sm_notify_pending,
eapol_sm_eap_param_needed,
eapol_sm_notify_cert,
+ eapol_sm_notify_permanent_id_req_denied,
eapol_sm_notify_status,
eapol_sm_notify_eap_error,
#ifdef CONFIG_EAP_PROXY
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index bbe2b6f..ad94cf5 100644
--- a/src/eapol_supp/eapol_supp_sm.h
+++ b/src/eapol_supp/eapol_supp_sm.h
@@ -255,6 +255,14 @@
const char *cert_hash);
/**
+ * permanent_id_req_denied_cb - Notify that the AT_PERMANENT_ID_REQ
+ * from the server was denied. This notification happens when the
+ * peer is in the strict conservative mode.
+ * @ctx: Callback context (ctx)
+ */
+ void (*permanent_id_req_denied_cb)(void *ctx);
+
+ /**
* cert_in_cb - Include server certificates in callback
*/
int cert_in_cb;
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index a1f8ae9..3c55c5a 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -592,6 +592,7 @@
ieee802_1x_kay_create_peer(const u8 *mi, u32 mn)
{
struct ieee802_1x_kay_peer *peer;
+ struct os_reltime now;
peer = os_zalloc(sizeof(*peer));
if (!peer) {
@@ -601,7 +602,8 @@
os_memcpy(peer->mi, mi, MI_LEN);
peer->mn = mn;
- peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+ os_get_reltime(&now);
+ peer->expire = now.sec + MKA_LIFE_TIME / 1000;
peer->sak_used = false;
peer->missing_sak_use_count = 0;
@@ -678,6 +680,7 @@
{
struct ieee802_1x_kay_peer *peer;
struct receive_sc *rxsc;
+ struct os_reltime now;
peer = ieee802_1x_kay_get_potential_peer(participant, mi);
if (!peer)
@@ -690,7 +693,8 @@
os_memcpy(&peer->sci, &participant->current_peer_sci,
sizeof(peer->sci));
peer->mn = mn;
- peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+ os_get_reltime(&now);
+ peer->expire = now.sec + MKA_LIFE_TIME / 1000;
wpa_printf(MSG_DEBUG, "KaY: Move potential peer to live peer");
ieee802_1x_kay_dump_peer(peer);
@@ -873,13 +877,15 @@
peer = ieee802_1x_kay_get_peer_sci(participant,
&body->actor_sci);
if (peer) {
- time_t new_expire;
+ os_time_t new_expire;
+ struct os_reltime now;
wpa_printf(MSG_WARNING,
"KaY: duplicated SCI detected - maybe active attacker or peer selected new MI - ignore MKPDU");
/* Reduce timeout to speed up this process but left the
* chance for old one to prove aliveness. */
- new_expire = time(NULL) + MKA_HELLO_TIME * 1.5 / 1000;
+ os_get_reltime(&now);
+ new_expire = now.sec + MKA_HELLO_TIME * 1.5 / 1000;
if (peer->expire > new_expire)
peer->expire = new_expire;
return NULL;
@@ -2130,6 +2136,7 @@
unsigned int key_len;
u8 *key;
struct macsec_ciphersuite *cs;
+ struct os_reltime now;
/* check condition for generating a fresh SAK:
* must have one live peer
@@ -2150,7 +2157,8 @@
* here only check first item and ingore
* && (!dl_list_empty(&participant->potential_peers))) {
*/
- if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) {
+ os_get_reltime(&now);
+ if ((now.sec - kay->dist_time) < MKA_LIFE_TIME / 1000) {
wpa_printf(MSG_ERROR,
"KaY: Life time has not elapsed since prior SAK distributed");
return -1;
@@ -2244,7 +2252,7 @@
if (kay->dist_an > 3)
kay->dist_an = 0;
- kay->dist_time = time(NULL);
+ kay->dist_time = now.sec;
return 0;
@@ -2548,17 +2556,19 @@
struct ieee802_1x_mka_participant *participant;
struct ieee802_1x_kay *kay;
struct ieee802_1x_kay_peer *peer, *pre_peer;
- time_t now = time(NULL);
+ struct os_reltime now;
bool lp_changed;
struct receive_sc *rxsc, *pre_rxsc;
struct transmit_sa *txsa, *pre_txsa;
+ os_get_reltime(&now);
+
participant = (struct ieee802_1x_mka_participant *)eloop_ctx;
kay = participant->kay;
wpa_printf(MSG_DEBUG, "KaY: Participant timer (ifname=%s)",
kay->if_name);
if (participant->cak_life) {
- if (now > participant->cak_life)
+ if (now.sec > participant->cak_life)
goto delete_mka;
}
@@ -2566,7 +2576,7 @@
* when the MKA life elapsed since its creating */
if (participant->mka_life) {
if (dl_list_empty(&participant->live_peers)) {
- if (now > participant->mka_life)
+ if (now.sec > participant->mka_life)
goto delete_mka;
} else {
participant->mka_life = 0;
@@ -2576,7 +2586,7 @@
lp_changed = false;
dl_list_for_each_safe(peer, pre_peer, &participant->live_peers,
struct ieee802_1x_kay_peer, list) {
- if (now > peer->expire) {
+ if (now.sec > peer->expire) {
wpa_printf(MSG_DEBUG, "KaY: Live peer removed");
wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
sizeof(peer->mi));
@@ -2634,7 +2644,7 @@
dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers,
struct ieee802_1x_kay_peer, list) {
- if (now > peer->expire) {
+ if (now.sec > peer->expire) {
wpa_printf(MSG_DEBUG, "KaY: Potential peer removed");
wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
sizeof(peer->mi));
@@ -3371,11 +3381,14 @@
return -1;
}
} else {
+ struct os_reltime now;
+
+ os_get_reltime(&now);
peer->missing_sak_use_count = 0;
/* Only update live peer watchdog after successful
* decode of all parameter sets */
- peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+ peer->expire = now.sec + MKA_LIFE_TIME / 1000;
}
} else {
/* MKPDU is from new or potential peer */
@@ -3674,8 +3687,12 @@
os_memcpy(participant->cak.key, cak->key, cak->len);
wpa_hexdump_key(MSG_DEBUG, "KaY: CAK", participant->cak.key,
participant->cak.len);
- if (life)
- participant->cak_life = life + time(NULL);
+ if (life) {
+ struct os_reltime now;
+ os_get_reltime(&now);
+
+ participant->cak_life = life + now.sec;
+ }
switch (mode) {
case EAP_EXCHANGE:
@@ -3783,7 +3800,10 @@
* some peer appears.
*/
if (mode != PSK) {
- participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
+ struct os_reltime now;
+ os_get_reltime(&now);
+
+ participant->mka_life = MKA_LIFE_TIME / 1000 + now.sec +
usecs / 1000000;
}
participant->mode = mode;
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index 11cf7b7..525679f 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -213,7 +213,7 @@
u32 dist_kn;
u32 rcvd_keys;
u8 dist_an;
- time_t dist_time;
+ os_time_t dist_time;
u8 mka_version;
u8 algo_agility[4];
diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index 7a04169..e4650b5 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -45,7 +45,7 @@
struct ieee802_1x_mka_sci sci;
u8 mi[MI_LEN];
u32 mn;
- time_t expire;
+ os_time_t expire;
bool is_key_server;
u8 key_server_priority;
bool macsec_desired;
@@ -135,8 +135,8 @@
struct ieee802_1x_mka_peer_id current_peer_id;
struct ieee802_1x_mka_sci current_peer_sci;
- time_t cak_life;
- time_t mka_life;
+ os_time_t cak_life;
+ os_time_t mka_life;
bool to_dist_sak;
bool to_use_sak;
bool new_sak;
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index db11387..05c79c0 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -67,7 +67,7 @@
defaults: ["wpa_supplicant_cflags_defaults"],
srcs: [":wpa_supplicant_srcs"],
shared_libs: [
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
"libbase",
"libbinder_ndk",
"libc",
@@ -216,6 +216,35 @@
"-Wno-unused-parameter",
"-Wno-unused-variable",
],
+ // Similar to suppressing clang compiler warnings, here we
+ // suppress clang-tidy warnings to reduce noises in Android build.log.
+ tidy_checks: [
+ "-android-cloexec-*",
+ "-bugprone-branch-clone",
+ "-bugprone-macro-parentheses",
+ "-bugprone-misplaced-widening-cast",
+ "-bugprone-signal-handler",
+ "-bugprone-signed-char-misuse",
+ "-bugprone-sizeof-expression",
+ "-bugprone-suspicious-string-compare",
+ "-bugprone-too-small-loop-variable",
+ "-cert-err34-c",
+ "-cert-msc30-c",
+ "-cert-msc50-cpp",
+ "-cert-msc54-cpp",
+ "-cert-sig30-c",
+ "-cert-str34-c",
+ "-clang-analyzer-core.NullDereference",
+ "-clang-analyzer-core.UndefinedBinaryOperatorResult",
+ "-clang-analyzer-deadcode.DeadStores",
+ "-clang-analyzer-optin.performance.Padding",
+ "-clang-analyzer-optin.portability.UnixAPI",
+ "-clang-analyzer-security.insecureAPI.UncheckedReturn",
+ "-clang-analyzer-unix.cstring.NullArg",
+ "-clang-analyzer-unix.Malloc",
+ "-clang-diagnostic-unused-but-set-variable",
+ "-misc-redundant-expression",
+ ],
}
// Generated by building wpa_supplicant and printing LOCAL_SRC_FILES.
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 1eaebde..1da9e61 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1812,7 +1812,7 @@
LOCAL_SHARED_LIBRARIES += libdbus
endif
ifeq ($(WPA_SUPPLICANT_USE_AIDL), y)
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant-V1-ndk
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant-V2-ndk
LOCAL_SHARED_LIBRARIES += libutils libbase
LOCAL_SHARED_LIBRARIES += libbinder_ndk
LOCAL_STATIC_LIBRARIES += libwpa_aidl
@@ -1884,7 +1884,7 @@
aidl/sta_network.cpp \
aidl/supplicant.cpp
LOCAL_SHARED_LIBRARIES := \
- android.hardware.wifi.supplicant-V1-ndk \
+ android.hardware.wifi.supplicant-V2-ndk \
libbinder_ndk \
libbase \
libutils \
diff --git a/wpa_supplicant/aidl/Android.bp b/wpa_supplicant/aidl/Android.bp
index 0785fe1..24c2079 100644
--- a/wpa_supplicant/aidl/Android.bp
+++ b/wpa_supplicant/aidl/Android.bp
@@ -33,7 +33,7 @@
defaults: ["wpa_supplicant_cflags_defaults"],
soc_specific: true,
shared_libs: [
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
"libbinder_ndk",
"libbase",
"libutils",
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index a7945cc..6bc13ad 100644
--- a/wpa_supplicant/aidl/aidl.cpp
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -186,6 +186,21 @@
wpa_s, ssid, rtype, default_txt);
}
+void wpas_aidl_notify_permanent_id_req_denied(
+ struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s || !wpa_s->global->aidl)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Notifying permanent_id_req denied to aidl control.");
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ return aidl_manager->notifyPermanentIdReqDenied(wpa_s);
+}
+
void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp)
@@ -671,7 +686,7 @@
}
void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{
if (!wpa_s || !ssid)
return;
@@ -684,7 +699,7 @@
if (!aidl_manager)
return;
- aidl_manager->notifyDppConfigReceived(wpa_s, ssid);
+ aidl_manager->notifyDppConfigReceived(wpa_s, ssid, conn_status_requested);
}
void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
@@ -692,6 +707,21 @@
wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_SENT);
}
+void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+ if (!wpa_s)
+ return;
+
+ wpa_printf(MSG_DEBUG, "wpas_aidl_notify_dpp_connection_status_sent %d ", result);
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ aidl_manager->notifyDppConnectionStatusSent(wpa_s, result);
+}
+
/* DPP Progress notifications */
void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
index 2f3c7a0..40eb860 100644
--- a/wpa_supplicant/aidl/aidl.h
+++ b/wpa_supplicant/aidl/aidl.h
@@ -37,6 +37,7 @@
int wpas_aidl_notify_network_request(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
enum wpa_ctrl_req_type rtype, const char *default_txt);
+ void wpas_aidl_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp);
@@ -103,8 +104,10 @@
void wpas_aidl_notify_eap_error(
struct wpa_supplicant *wpa_s, int error_code);
void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
+ struct wpa_ssid *ssid, bool conn_status_requested);
void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+ void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
@@ -171,6 +174,8 @@
{
return 0;
}
+static void wpas_aidl_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s)
+{}
static void wpas_aidl_notify_anqp_query_done(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp)
@@ -252,12 +257,13 @@
struct wpa_supplicant *wpa_s, int error_code)
{}
static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{}
-static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
static void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
{}
+void wpas_aidl_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{}
static void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{}
static void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 1791b2b..063d400 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -39,6 +39,7 @@
const std::vector<uint8_t> kZeroBssid = {0, 0, 0, 0, 0, 0};
using aidl::android::hardware::wifi::supplicant::GsmRand;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
/**
* Check if the provided |wpa_supplicant| structure represents a P2P iface or
@@ -655,38 +656,46 @@
return 1;
// Invoke the |onStateChanged| method on all registered callbacks.
- uint32_t aidl_network_id = UINT32_MAX;
- std::vector<uint8_t> aidl_ssid;
+ SupplicantStateChangeData aidl_state_change_data = {};
+ aidl_state_change_data.id = UINT32_MAX;
+ aidl_state_change_data.newState = static_cast<StaIfaceCallbackState>(wpa_s->wpa_state);
+
if (wpa_s->current_ssid) {
- aidl_network_id = wpa_s->current_ssid->id;
- aidl_ssid.assign(
+ aidl_state_change_data.id = wpa_s->current_ssid->id;
+ std::vector<uint8_t> aidl_ssid(
wpa_s->current_ssid->ssid,
wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+ aidl_state_change_data.ssid = aidl_ssid;
+ wpa_printf(MSG_INFO, "assoc key_mgmt 0x%x network key_mgmt 0x%x",
+ wpa_s->key_mgmt, wpa_s->current_ssid->key_mgmt);
}
- std::vector<uint8_t> bssid;
+ std::vector<uint8_t> aidl_bssid;
// wpa_supplicant sets the |pending_bssid| field when it starts a
// connection. Only after association state does it update the |bssid|
// field. So, in the AIDL callback send the appropriate bssid.
if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
- bssid = macAddrToVec(wpa_s->pending_bssid);
+ aidl_bssid = macAddrToVec(wpa_s->pending_bssid);
} else {
- bssid = macAddrToVec(wpa_s->bssid);
+ aidl_bssid = macAddrToVec(wpa_s->bssid);
}
- bool fils_hlp_sent =
+ aidl_state_change_data.bssid = aidl_bssid;
+
+ aidl_state_change_data.filsHlpSent =
(wpa_auth_alg_fils(wpa_s->auth_alg) &&
!dl_list_empty(&wpa_s->fils_hlp_req) &&
(wpa_s->wpa_state == WPA_COMPLETED)) ? true : false;
+ aidl_state_change_data.keyMgmtMask = (KeyMgmtMask) wpa_s->key_mgmt;
+ // wpa_supplicant sets the frequency on receiving the EVENT_ASSOC.
+ aidl_state_change_data.frequencyMhz =
+ wpa_s->wpa_state >= WPA_ASSOCIATED ? wpa_s->assoc_freq : 0;
// Invoke the |onStateChanged| method on all registered callbacks.
std::function<
ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
func = std::bind(
- &ISupplicantStaIfaceCallback::onStateChanged,
+ &ISupplicantStaIfaceCallback::onSupplicantStateChanged,
std::placeholders::_1,
- static_cast<StaIfaceCallbackState>(
- wpa_s->wpa_state),
- bssid, aidl_network_id, aidl_ssid,
- fils_hlp_sent);
+ aidl_state_change_data);
callWithEachStaIfaceCallback(
misc_utils::charBufToString(wpa_s->ifname), func);
return 0;
@@ -759,6 +768,30 @@
}
/**
+ * Notify that the AT_PERMANENT_ID_REQ is denied from eap_peer when the strict
+ * conservative peer mode is enabled.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+*/
+void AidlManager::notifyPermanentIdReqDenied(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s->current_ssid) {
+ wpa_printf(MSG_ERROR, "Current network NULL. Drop permanent_id_req_denied event!");
+ return;
+ }
+ struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+
+ callWithEachStaNetworkCallback(
+ misc_utils::charBufToString(wpa_s->ifname),
+ current_ssid->id,
+ std::bind(
+ &ISupplicantStaNetworkCallback::
+ onPermanentIdReqDenied,
+ std::placeholders::_1));
+}
+
+/**
* Notify all listeners about the end of an ANQP query.
*
* @param wpa_s |wpa_supplicant| struct corresponding to the interface.
@@ -1350,14 +1383,22 @@
dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
}
+ P2pGroupStartedEventParams params;
+ params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
+ params.isGroupOwner = aidl_is_go;
+ params.ssid = byteArrToVec(ssid->ssid, ssid->ssid_len);
+ params.frequencyMHz = aidl_freq;
+ params.psk = aidl_psk;
+ params.passphrase = misc_utils::charBufToString(ssid->passphrase);
+ params.isPersistent = aidl_is_persistent;
+ params.goDeviceAddress = macAddrToVec(wpa_group_s->go_dev_addr);
+ params.goInterfaceAddress = aidl_is_go ? macAddrToVec(wpa_group_s->own_addr) :
+ macAddrToVec(wpa_group_s->current_bss->bssid);
+
callWithEachP2pIfaceCallback(
misc_utils::charBufToString(wpa_s->ifname),
- std::bind(
- &ISupplicantP2pIfaceCallback::onGroupStarted,
- std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
- aidl_is_go, byteArrToVec(ssid->ssid, ssid->ssid_len),
- aidl_freq, aidl_psk, misc_utils::charBufToString(ssid->passphrase),
- macAddrToVec(wpa_group_s->go_dev_addr), aidl_is_persistent));
+ std::bind(&ISupplicantP2pIfaceCallback::onGroupStartedWithParams,
+ std::placeholders::_1, params));
}
void AidlManager::notifyP2pGroupRemoved(
@@ -1559,19 +1600,18 @@
* @param config Configuration object
*/
void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *config)
+ struct wpa_ssid *config, bool conn_status_requested)
{
- DppAkm securityAkm;
- DppConnectionKeys aidl_keys{};
std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ DppConfigurationData aidl_dpp_config_data = {};
if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
- securityAkm = DppAkm::SAE;
+ aidl_dpp_config_data.securityAkm = DppAkm::SAE;
} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
- securityAkm = DppAkm::PSK;
+ aidl_dpp_config_data.securityAkm = DppAkm::PSK;
} else if (config->key_mgmt & WPA_KEY_MGMT_DPP) {
- securityAkm = DppAkm::DPP;
+ aidl_dpp_config_data.securityAkm = DppAkm::DPP;
} else {
/* Unsupported AKM */
wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
@@ -1580,29 +1620,31 @@
return;
}
- std::string passphrase = misc_utils::charBufToString(config->passphrase);
+ aidl_dpp_config_data.password = misc_utils::charBufToString(config->passphrase);
+ aidl_dpp_config_data.psk = byteArrToVec(config->psk, 32);
std::vector<uint8_t> aidl_ssid(
config->ssid,
config->ssid + config->ssid_len);
+ aidl_dpp_config_data.ssid = aidl_ssid;
- if (securityAkm == DppAkm::DPP) {
+ if (aidl_dpp_config_data.securityAkm == DppAkm::DPP) {
std::string connector_str = misc_utils::charBufToString(config->dpp_connector);
- aidl_keys.connector = std::vector<uint8_t>(connector_str.begin(),
- connector_str.end());
- aidl_keys.cSign = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
- aidl_keys.netAccessKey = byteArrToVec(config->dpp_netaccesskey,
- config->dpp_netaccesskey_len);
+ aidl_dpp_config_data.dppConnectionKeys.connector
+ = std::vector<uint8_t>(connector_str.begin(), connector_str.end());
+ aidl_dpp_config_data.dppConnectionKeys.cSign
+ = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
+ aidl_dpp_config_data.dppConnectionKeys.netAccessKey
+ = byteArrToVec(config->dpp_netaccesskey, config->dpp_netaccesskey_len);
}
+ aidl_dpp_config_data.connStatusRequested = conn_status_requested;
/* At this point, the network is already registered, notify about new
* received configuration
*/
callWithEachStaIfaceCallback(aidl_ifname,
std::bind(
- &ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
- std::placeholders::_1, aidl_ssid, passphrase,
- byteArrToVec(config->psk, 32), securityAkm,
- aidl_keys));
+ &ISupplicantStaIfaceCallback::onDppConfigReceived,
+ std::placeholders::_1, aidl_dpp_config_data));
}
/**
@@ -1619,6 +1661,55 @@
std::placeholders::_1));
}
+DppStatusErrorCode convertSupplicantDppStatusErrorCodeToAidl(
+ enum dpp_status_error code)
+{
+ switch (code) {
+ case DPP_STATUS_OK:
+ return DppStatusErrorCode::SUCCESS;
+ case DPP_STATUS_NOT_COMPATIBLE:
+ return DppStatusErrorCode::NOT_COMPATIBLE;
+ case DPP_STATUS_AUTH_FAILURE:
+ return DppStatusErrorCode::AUTH_FAILURE;
+ case DPP_STATUS_UNWRAP_FAILURE:
+ return DppStatusErrorCode::UNWRAP_FAILURE;
+ case DPP_STATUS_BAD_GROUP:
+ return DppStatusErrorCode::BAD_GROUP;
+ case DPP_STATUS_CONFIGURE_FAILURE:
+ return DppStatusErrorCode::CONFIGURE_FAILURE;
+ case DPP_STATUS_RESPONSE_PENDING:
+ return DppStatusErrorCode::RESPONSE_PENDING;
+ case DPP_STATUS_INVALID_CONNECTOR:
+ return DppStatusErrorCode::INVALID_CONNECTOR;
+ case DPP_STATUS_CONFIG_REJECTED:
+ return DppStatusErrorCode::CONFIG_REJECTED;
+ case DPP_STATUS_NO_MATCH:
+ return DppStatusErrorCode::NO_MATCH;
+ case DPP_STATUS_NO_AP:
+ return DppStatusErrorCode::NO_AP;
+ case DPP_STATUS_CONFIGURE_PENDING:
+ return DppStatusErrorCode::CONFIGURE_PENDING;
+ case DPP_STATUS_CSR_NEEDED:
+ return DppStatusErrorCode::CSR_NEEDED;
+ case DPP_STATUS_CSR_BAD:
+ return DppStatusErrorCode::CSR_BAD;
+ case DPP_STATUS_NEW_KEY_NEEDED:
+ return DppStatusErrorCode::NEW_KEY_NEEDED;
+ default:
+ return DppStatusErrorCode::UNKNOWN;
+ }
+}
+
+void AidlManager::notifyDppConnectionStatusSent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+ std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ callWithEachStaIfaceCallback(aidl_ifname,
+ std::bind(&ISupplicantStaIfaceCallback::onDppConnectionStatusResultSent,
+ std::placeholders::_1,
+ convertSupplicantDppStatusErrorCodeToAidl(result)));
+}
+
/**
* Notify listener about a DPP failure event
*
@@ -1906,24 +1997,33 @@
callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
}
-void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_group_s, int frequency)
+void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_s, int frequency)
{
- if (!wpa_group_s || !wpa_group_s->parent)
+ if (!wpa_s)
return;
- // For group notifications, need to use the parent iface for callbacks.
- struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
- if (!wpa_s) {
+ std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+ struct wpa_supplicant *wpa_p2pdev_s = getTargetP2pIfaceForGroup(wpa_s);
+ if (wpa_p2pdev_s) {
+ // Notify frequency changed event on P2P interface
+ const std::function<
+ ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+ func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
+ std::placeholders::_1, aidl_ifname, frequency);
+ // For group notifications, need to use the parent iface for callbacks.
+ callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_p2pdev_s->ifname), func);
+ } else if (wpa_s->current_ssid) {
+ // Notify frequency changed event on STA interface
+ const std::function<
+ ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+ func = std::bind(
+ &ISupplicantStaIfaceCallback::onBssFrequencyChanged,
+ std::placeholders::_1, frequency);
+ callWithEachStaIfaceCallback(aidl_ifname, func);
+ } else {
wpa_printf(MSG_INFO, "Drop frequency changed event");
return;
- }
-
- const std::function<
- ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
- func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
- std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
- frequency);
- callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+ }
}
void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index 1ed6899..5224ef2 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -61,6 +61,8 @@
int notifyNetworkRequest(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
const char *param);
+ void notifyPermanentIdReqDenied(
+ struct wpa_supplicant *wpa_s);
void notifyAnqpQueryDone(
struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
const struct wpa_bss_anqp *anqp);
@@ -125,8 +127,11 @@
const u8 *p2p_dev_addr);
void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *config);
+ struct wpa_ssid *config,
+ bool conn_status_requested);
void notifyDppConfigSent(struct wpa_supplicant *wpa_s);
+ void notifyDppConnectionStatusSent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code);
void notifyDppFailure(struct wpa_supplicant *wpa_s,
DppFailureCode code);
diff --git a/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml b/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
index 3dc9b02..b80dadd 100644
--- a/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
+++ b/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
@@ -1,6 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.wifi.supplicant</name>
+ <version>2</version>
<fqname>ISupplicant/default</fqname>
</hal>
</manifest>
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
index 805ece2..61d266f 100644
--- a/wpa_supplicant/aidl/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -992,6 +992,9 @@
if (go_intent > 15) {
return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
}
+ if (peer_address.size() != ETH_ALEN) {
+ return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+ }
int go_intent_signed = join_existing_group ? -1 : go_intent;
p2p_wps_method wps_method = {};
switch (provision_method) {
@@ -1087,6 +1090,9 @@
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
+ if (peer_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
if (wpas_p2p_reject(wpa_s, peer_address.data())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
@@ -1099,6 +1105,9 @@
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+ if (peer_address.size() != ETH_ALEN) {
+ return {createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
if (wpas_p2p_invite_group(
wpa_s, group_ifname.c_str(), peer_address.data(),
go_device_address.data(), is6GhzAllowed(wpa_s))) {
@@ -1121,6 +1130,9 @@
if (ssid == NULL || ssid->disabled != 2) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
}
+ if (peer_address.size() != ETH_ALEN) {
+ return {createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
if (wpas_p2p_invite(
wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, 0, he, edmg, is6GhzAllowed(wpa_s))) {
@@ -1284,6 +1296,9 @@
if (!query_buf) {
return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
+ if (peer_address.size() != ETH_ALEN) {
+ return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
? nullptr
: peer_address.data();
@@ -1330,6 +1345,9 @@
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
+ if (bssid.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
const uint8_t* bssid_addr =
is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
#ifdef CONFIG_AP
@@ -1378,6 +1396,9 @@
if (!wpa_group_s) {
return {"", createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
}
+ if (bssid.size() != ETH_ALEN) {
+ return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
const uint8_t* bssid_addr =
is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
int pin = wpas_wps_start_pin(
@@ -1410,6 +1431,9 @@
const std::vector<uint8_t>& type)
{
std::array<uint8_t, 8> type_arr;
+ if (type.size() != 8) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
std::copy_n(type.begin(), 8, type_arr.begin());
return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
}
@@ -1732,6 +1756,9 @@
const std::vector<uint8_t>& peer_address, bool isLegacyClient)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+ if (peer_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
wpas_p2p_remove_client(wpa_s, peer_address.data(), isLegacyClient? 1 : 0);
return ndk::ScopedAStatus::ok();
}
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index 7a07cc1..1431340 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -50,6 +50,7 @@
WIDTH_80P80 = 4,
WIDTH_5 = 5,
WIDTH_10 = 6,
+ WIDTH_320 = 7,
WIDTH_INVALID = -1
};
@@ -810,6 +811,14 @@
&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
}
+::ndk::ScopedAStatus StaIface::getSignalPollResults(
+ std::vector<SignalPollResult> *results)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_UNKNOWN,
+ &StaIface::getSignalPollResultsInternal, results);
+}
+
std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
{
return {ifname_, ndk::ScopedAStatus::ok()};
@@ -1747,7 +1756,9 @@
if (wpa_s->connection_set) {
capa.legacyMode = LegacyMode::UNKNOWN;
- if (wpa_s->connection_he) {
+ if (wpa_s->connection_eht) {
+ capa.technology = WifiTechnology::EHT;
+ } else if (wpa_s->connection_he) {
capa.technology = WifiTechnology::HE;
} else if (wpa_s->connection_vht) {
capa.technology = WifiTechnology::VHT;
@@ -1778,6 +1789,9 @@
case CHAN_WIDTH_80P80:
capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
break;
+ case CHAN_WIDTH_320:
+ capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_320;
+ break;
default:
capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
break;
@@ -1817,6 +1831,12 @@
mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
+ mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SET_TLS_MINIMUM_VERSION);
+
+#ifdef EAP_TLSV1_3
+ mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TLS_V1_3);
+#endif
+
wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
return {static_cast<WpaDriverCapabilitiesMask>(mask),
@@ -1930,10 +1950,75 @@
std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
MloLinksInfo linksInfo;
+ MloLink link;
+
+ if (!wpa_s->valid_links)
+ return {linksInfo, ndk::ScopedAStatus::ok()};
+
+ for (int i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ if (!(wpa_s->valid_links & BIT(i)))
+ continue;
+
+ wpa_printf(MSG_DEBUG, "Add MLO Link ID %d info", i);
+ link.linkId = i;
+ link.staLinkMacAddress.assign(wpa_s->links[i].addr, wpa_s->links[i].addr + ETH_ALEN);
+ // TODO (b/259710591): Once suppllicant implements TID-to-link
+ // mapping, copy it here. Mapping can be changed in two
+ // scenarios
+ // 1. Mandatory mapping from AP
+ // 2. Negotiated mapping
+ // After association, framework call this API to get
+ // MloLinksInfo. If there is an update in mapping later, notify
+ // framework on the change using the callback,
+ // ISupplicantStaIfaceCallback.onMloLinksInfoChanged() with
+ // reason code as TID_TO_LINK_MAP. In absence of an advertised
+ // mapping by the AP, a default TID-to-link mapping is assumed
+ // unless an individual TID-to-link mapping is successfully
+ // negotiated.
+ link.tidsUplinkMap = 0xFF;
+ link.tidsDownlinkMap = 0xFF;
+ linksInfo.links.push_back(link);
+ }
+
return {linksInfo, ndk::ScopedAStatus::ok()};
}
+std::pair<std::vector<SignalPollResult>, ndk::ScopedAStatus>
+StaIface::getSignalPollResultsInternal()
+{
+ std::vector<SignalPollResult> results;
+ struct wpa_signal_info si;
+ struct wpa_mlo_signal_info mlo_si;
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+
+ if (wpa_s->valid_links && wpa_drv_mlo_signal_poll(wpa_s, &mlo_si)) {
+ for (int i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ if (!(mlo_si.valid_links & BIT(i)))
+ continue;
+
+ SignalPollResult result;
+ result.linkId = 0;
+ result.currentRssiDbm = mlo_si.links[i].current_signal;
+ result.txBitrateMbps = mlo_si.links[i].current_txrate / 1000;
+ result.rxBitrateMbps = mlo_si.links[i].current_rxrate / 1000;
+ result.frequencyMhz = mlo_si.links[i].frequency;
+ results.push_back(result);
+ }
+ } else if (wpa_drv_signal_poll(wpa_s, &si) == 0) {
+ SignalPollResult result;
+ result.linkId = 0;
+ result.currentRssiDbm = si.current_signal;
+ result.txBitrateMbps = si.current_txrate / 1000;
+ result.rxBitrateMbps = si.current_rxrate / 1000;
+ result.frequencyMhz = si.frequency;
+ results.push_back(result);
+ }
+
+ return {results, ndk::ScopedAStatus::ok()};
+}
+
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this iface.
diff --git a/wpa_supplicant/aidl/sta_iface.h b/wpa_supplicant/aidl/sta_iface.h
index 0ed29d8..5371468 100644
--- a/wpa_supplicant/aidl/sta_iface.h
+++ b/wpa_supplicant/aidl/sta_iface.h
@@ -157,6 +157,8 @@
const std::vector<QosPolicyStatus>& in_qosPolicyStatusList) override;
::ndk::ScopedAStatus removeAllQosPolicies() override;
::ndk::ScopedAStatus getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) override;
+ ::ndk::ScopedAStatus getSignalPollResults(
+ std::vector<SignalPollResult>* results) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -261,6 +263,8 @@
const std::vector<QosPolicyStatus>& qos_policy_status_list);
ndk::ScopedAStatus removeAllQosPoliciesInternal();
std::pair<MloLinksInfo, ndk::ScopedAStatus> getConnectionMloLinksInfoInternal();
+ std::pair<std::vector<SignalPollResult>, ndk::ScopedAStatus>
+ getSignalPollResultsInternal();
struct wpa_supplicant* retrieveIfacePtr();
// Reference to the global wpa_struct. This is assumed to be valid for
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index 61c71a1..db13509 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -304,6 +304,15 @@
in_identity);
}
+::ndk::ScopedAStatus StaNetwork::setStrictConservativePeerMode(
+ bool in_enable)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+ &StaNetwork::setStrictConservativePeerModeInternal,
+ in_enable);
+}
+
::ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity)
{
@@ -871,6 +880,14 @@
&StaNetwork::setRoamingConsortiumSelectionInternal, in_selectedRcoi);
}
+::ndk::ScopedAStatus StaNetwork::setMinimumTlsVersionEapPhase1Param(
+ TlsVersion in_tlsVersion)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+ &StaNetwork::setMinimumTlsVersionEapPhase1ParamInternal, in_tlsVersion);
+}
+
std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getIdInternal()
{
return {network_id_, ndk::ScopedAStatus::ok()};
@@ -1238,6 +1255,13 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus StaNetwork::setStrictConservativePeerModeInternal(bool enable)
+{
+ struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+ wpa_ssid->eap.strict_conservative_peer_mode = enable ? 1 : 0;
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentityInternal(
const std::vector<uint8_t> &identity)
{
@@ -2005,10 +2029,13 @@
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
int val = enable == true ? 1 : 0;
- std::string suiteb_phase1("tls_suiteb=" + std::to_string(val));
+ std::string phase1_params("tls_suiteb=" + std::to_string(val));
+ if (wpa_ssid->eap.phase1 != NULL) {
+ phase1_params.append(wpa_ssid->eap.phase1);
+ }
if (setStringKeyFieldAndResetState(
- suiteb_phase1.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+ phase1_params.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
@@ -2152,10 +2179,19 @@
KeyMgmtMask mask)
{
uint32_t key_mgmt_mask = static_cast<uint32_t>(mask);
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
}
+#ifdef CONFIG_SAE
+ struct wpa_driver_capa capa;
+ int res = wpa_drv_get_capa(wpa_s, &capa);
+ if ((res == 0) && (key_mgmt_mask & WPA_KEY_MGMT_SAE) &&
+ (capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY)) {
+ key_mgmt_mask |= WPA_KEY_MGMT_SAE_EXT_KEY;
+ }
+#endif
setFastTransitionKeyMgmt(key_mgmt_mask);
if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
@@ -2489,6 +2525,11 @@
(capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE;
}
+ if ((key_mgmt_mask & WPA_KEY_MGMT_SAE_EXT_KEY) &&
+ (capa.key_mgmt_iftype[WPA_IF_STATION] &
+ WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY)) {
+ key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
+ }
#endif
#ifdef CONFIG_FILS
if ((key_mgmt_mask & WPA_KEY_MGMT_FILS_SHA256) &&
@@ -2597,6 +2638,41 @@
#endif
}
+ndk::ScopedAStatus StaNetwork::setMinimumTlsVersionEapPhase1ParamInternal(TlsVersion tlsVersion)
+{
+ struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+ std::string phase1_params;
+ if (wpa_ssid->eap.phase1 != NULL) {
+ phase1_params.append(wpa_ssid->eap.phase1);
+ }
+ if (tlsVersion < TlsVersion::TLS_V1_0) {
+ return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+ }
+ // Fallback to disable lower version TLS cascadingly.
+ switch (tlsVersion) {
+ case TlsVersion::TLS_V1_3:
+ phase1_params.append("tls_disable_tlsv1_2=1");
+ FALLTHROUGH_INTENDED;
+ case TlsVersion::TLS_V1_2:
+ phase1_params.append("tls_disable_tlsv1_1=1");
+ FALLTHROUGH_INTENDED;
+ case TlsVersion::TLS_V1_1:
+ phase1_params.append("tls_disable_tlsv1_0=1");
+ FALLTHROUGH_INTENDED;
+ case TlsVersion::TLS_V1_0:
+ FALLTHROUGH_INTENDED;
+ default:
+ // no restriction
+ break;
+ }
+
+ if (setStringKeyFieldAndResetState(
+ phase1_params.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace supplicant
} // namespace wifi
} // namespace hardware
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
index 524f44a..f794844 100644
--- a/wpa_supplicant/aidl/sta_network.h
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -22,6 +22,7 @@
#include <aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.h>
#include <aidl/android/hardware/wifi/supplicant/SaeH2eMode.h>
#include <aidl/android/hardware/wifi/supplicant/DppConnectionKeys.h>
+#include <aidl/android/hardware/wifi/supplicant/TlsVersion.h>
extern "C"
{
@@ -84,6 +85,8 @@
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapEncryptedImsiIdentity(
const std::vector<uint8_t>& in_identity) override;
+ ::ndk::ScopedAStatus setStrictConservativePeerMode(
+ bool in_enable) override;
::ndk::ScopedAStatus setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapPassword(
@@ -173,6 +176,8 @@
::ndk::ScopedAStatus enableSaePkOnlyMode(bool in_enable) override;
::ndk::ScopedAStatus setRoamingConsortiumSelection(
const std::vector<uint8_t>& in_selectedRcoi) override;
+ ::ndk::ScopedAStatus setMinimumTlsVersionEapPhase1Param(
+ TlsVersion in_tlsVersion) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -209,6 +214,8 @@
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapEncryptedImsiIdentityInternal(
const std::vector<uint8_t>& identity);
+ ndk::ScopedAStatus setStrictConservativePeerModeInternal(
+ bool enable);
ndk::ScopedAStatus setEapAnonymousIdentityInternal(
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapPasswordInternal(
@@ -302,6 +309,7 @@
ndk::ScopedAStatus enableSaePkOnlyModeInternal(bool enable);
ndk::ScopedAStatus setRoamingConsortiumSelectionInternal(
const std::vector<uint8_t>& selectedRcoi);
+ ndk::ScopedAStatus setMinimumTlsVersionEapPhase1ParamInternal(TlsVersion tlsVersion);
struct wpa_ssid* retrieveNetworkPtr();
struct wpa_supplicant* retrieveIfacePtr();
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 52e4c04..bfdd53e 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -80,6 +80,7 @@
# EAP-TLS
CONFIG_EAP_TLS=y
+CONFIG_EAP_TLSV1_3=y
# EAL-PEAP
CONFIG_EAP_PEAP=y
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 065b6fb..2b1bdeb 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2529,6 +2529,7 @@
{ INTe(sim_num, sim_num) },
{ STRe(imsi_privacy_cert, imsi_privacy_cert) },
{ STRe(imsi_privacy_attr, imsi_privacy_attr) },
+ { INTe(strict_conservative_peer_mode, strict_conservative_peer_mode) },
{ STRe(openssl_ciphers, openssl_ciphers) },
{ INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */
@@ -3953,6 +3954,11 @@
return 0;
}
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0) {
+ cred->strict_conservative_peer_mode = atoi(val);
+ return 0;
+ }
+
if (line) {
wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
line, var);
@@ -4109,6 +4115,9 @@
if (os_strcmp(var, "imsi_privacy_attr") == 0)
return alloc_strdup(cred->imsi_privacy_attr);
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0)
+ return alloc_int_str(cred->strict_conservative_peer_mode);
+
if (os_strcmp(var, "milenage") == 0) {
if (!(cred->milenage))
return NULL;
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index a81e9eb..0316e9b 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -202,6 +202,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in convervative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never send the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* engine - Use an engine for private key operations
*/
int engine;
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 260df8f..372a57b 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1044,6 +1044,9 @@
if (cred->imsi_privacy_attr)
fprintf(f, "\timsi_privacy_attr=\"%s\"\n",
cred->imsi_privacy_attr);
+ if (cred->strict_conservative_peer_mode)
+ fprintf(f,"\tstrict_conservative_peer_mode=\"%d\"\n",
+ cred->strict_conservative_peer_mode);
}
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 55dcd70..593da3a 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -419,12 +419,21 @@
DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
MAC2STR(auth->peer_mac_addr), auth->curr_freq,
DPP_PA_CONNECTION_STATUS_RESULT);
- offchannel_send_action(wpa_s, auth->curr_freq,
- auth->peer_mac_addr, wpa_s->own_addr, broadcast,
- wpabuf_head(msg), wpabuf_len(msg),
- 500, wpas_dpp_tx_status, 0);
+ if (offchannel_send_action(wpa_s, auth->curr_freq,
+ auth->peer_mac_addr, wpa_s->own_addr, broadcast,
+ wpabuf_head(msg), wpabuf_len(msg),
+ 500, wpas_dpp_tx_status, 0) < 0) {
+ wpas_notify_dpp_connection_status_sent(wpa_s, result);
+ wpabuf_free(msg);
+ dpp_auth_deinit(wpa_s->dpp_auth);
+ wpa_s->dpp_auth = NULL;
+ return;
+ }
+
wpabuf_free(msg);
+ auth->conn_result_status = result;
+ auth->tx_conn_status_result_started = 1;
/* This exchange will be terminated in the TX status handler */
auth->remove_on_tx_status = 1;
@@ -491,6 +500,9 @@
#endif /* CONFIG_DPP2 */
if (wpa_s->dpp_auth->remove_on_tx_status) {
+ if (auth->tx_conn_status_result_started) {
+ wpas_notify_dpp_connection_status_sent(wpa_s, auth->conn_result_status);
+ }
wpa_printf(MSG_DEBUG,
"DPP: Terminate authentication exchange due to a request to do so on TX status");
eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
@@ -1476,7 +1488,7 @@
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
- wpas_notify_dpp_config_received(wpa_s, ssid);
+ wpas_notify_dpp_config_received(wpa_s, ssid, auth->conn_status_requested ? 1 : 0);
if (wpa_s->conf->dpp_config_processing == 2)
ssid->disabled = 0;
@@ -1829,7 +1841,7 @@
wpabuf_free(msg);
/* This exchange will be terminated in the TX status handler */
- if (wpa_s->conf->dpp_config_processing < 2 ||
+ if (wpa_s->conf->dpp_config_processing < 1 ||
wpa_s->dpp_conf_backup_received)
auth->remove_on_tx_status = 1;
return;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2d364bc..b066d62 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3079,7 +3079,8 @@
get_supported_channel_width(&req_elems);
enum chan_width ap_operation_chan_width =
get_operation_channel_width(&resp_elems);
- if (wpa_s->connection_vht || wpa_s->connection_he) {
+ if (wpa_s->connection_vht || wpa_s->connection_he ||
+ wpa_s->connection_eht) {
wpa_s->connection_channel_bandwidth =
get_sta_operation_chan_width(ap_operation_chan_width,
sta_supported_chan_width);
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 6198bd7..acd9044 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1077,6 +1077,12 @@
goto fail;
}
+ if (cred->strict_conservative_peer_mode) {
+ if (wpa_config_set_quoted(ssid, "strict_conservative_peer_mode",
+ "1") < 0)
+ goto fail;
+ }
+
wpa_s->next_ssid = ssid;
wpa_config_update_prio_list(wpa_s->conf);
if (!only_add)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a544c94..7e6d042 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -280,6 +280,12 @@
}
+void wpas_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s)
+{
+ wpas_aidl_notify_permanent_id_req_denied(wpa_s);
+}
+
+
void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
{
if (wpa_s->p2p_mgmt)
@@ -1103,13 +1109,13 @@
/* DPP Success notifications */
void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
+ struct wpa_ssid *ssid, bool conn_status_requested)
{
#ifdef CONFIG_DPP
if (!wpa_s)
return;
- wpas_aidl_notify_dpp_config_received(wpa_s, ssid);
+ wpas_aidl_notify_dpp_config_received(wpa_s, ssid, conn_status_requested);
#endif /* CONFIG_DPP */
}
@@ -1123,6 +1129,17 @@
#endif /* CONFIG_DPP */
}
+void wpas_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result)
+{
+#ifdef CONFIG_DPP2
+ if (!wpa_s)
+ return;
+
+ wpas_aidl_notify_dpp_connection_status_sent(wpa_s, result);
+#endif /* CONFIG_DPP2 */
+}
+
/* DPP Progress notifications */
void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 996be84..e1b9f17 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -48,6 +48,7 @@
struct wpa_ssid *ssid,
enum wpa_ctrl_req_type rtype,
const char *default_txt);
+void wpas_notify_permanent_id_req_denied(struct wpa_supplicant *wpa_s);
void wpas_notify_scanning(struct wpa_supplicant *wpa_s);
void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success);
void wpas_notify_scan_results(struct wpa_supplicant *wpa_s);
@@ -180,8 +181,10 @@
void wpas_notify_hs20_rx_terms_and_conditions_acceptance(
struct wpa_supplicant *wpa_s, const char *url);
void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid);
+ struct wpa_ssid *ssid, bool conn_status_requested);
void wpas_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_connection_status_sent(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error result);
void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
void wpas_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
void wpas_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 56dd5b9..772067f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2035,7 +2035,8 @@
if ((wpa_s->key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) &&
IS_CROSS_AKM_ROAM_KEY_MGMT(ssid->key_mgmt) &&
(wpa_s->group_cipher == WPA_CIPHER_CCMP) &&
- (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)) {
+ (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) &&
+ (wpa_s->wpa_proto == WPA_PROTO_RSN)) {
wpa_s->key_mgmt = WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK;
wpa_dbg(wpa_s, MSG_INFO,
"WPA: Updating to KEY_MGMT SAE+PSK for seamless roaming");
@@ -8366,6 +8367,8 @@
ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->auth_failures, dur, reason) + 1;
char *msg = os_malloc(msg_len);
+ if (!msg)
+ return;
snprintf(msg, msg_len, format_str,
ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->auth_failures, dur, reason);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 8262eef..b6a1a74 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1175,6 +1175,14 @@
# unencrypted identity with EAP types that support different tunnelled
# identity, e.g., EAP-TTLS). This field can also be used with
# EAP-SIM/AKA/AKA' to store the pseudonym identity.
+# strict_conservative_peer_mode: Whether the strict conservative peer mode
+# is enabled. This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+# for EAP-SIM/AKA/AKA'. In non-strict convervative peer mode, a client
+# error would be sent to the server, but the mode will send the permanent
+# identity in some special cases according to 4.6.2 of RFC 4187; With the
+# strict mode, the permanent identity is never sent to the server.
+# 0 = disabled (default)
+# 1 = enabled
# password: Password string for EAP. This field can include either the
# plaintext password (using ASCII or hex string) or a NtPasswordHash
# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index e13ea8f..a733ae3 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1093,6 +1093,12 @@
wpa_drv_set_supp_port(wpa_s, authorized);
}
+static void wpa_supplicant_permanent_id_req_denied_cb(void *ctx)
+{
+ struct wpas_supplicant *wpa_s = ctx;
+
+ wpas_notify_permanent_id_req_denied(wpa_s);
+}
static void wpa_supplicant_cert_cb(void *ctx, struct tls_cert_data *cert,
const char *cert_hash)
@@ -1238,6 +1244,7 @@
ctx->port_cb = wpa_supplicant_port_cb;
ctx->cb = wpa_supplicant_eapol_cb;
ctx->cert_cb = wpa_supplicant_cert_cb;
+ ctx->permanent_id_req_denied_cb = wpa_supplicant_permanent_id_req_denied_cb;
ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
ctx->status_cb = wpa_supplicant_status_cb;
ctx->eap_error_cb = wpa_supplicant_eap_error_cb;