Merge "P2P: introduce force_go_bssid bool to avoid changing p2p join behavior"
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..0c5d96b 100644
--- a/hostapd/Android.bp
+++ b/hostapd/Android.bp
@@ -55,7 +55,6 @@
"libcrypto",
"libssl",
"libnl",
- "libkeystore-wifi-hidl",
],
relative_install_path: "hw",
soc_specific: true,
@@ -169,6 +168,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 +346,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..5c423eb 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)
@@ -2705,9 +2712,9 @@
#define WFA_CAPA_QM_DSCP_POLICY BIT(0)
#define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
#define WPA_KEY_MGMT_CROSS_AKM_ROAM (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK)
#define IS_CROSS_AKM_ROAM_KEY_MGMT(key_mgmt) \
((key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) == WPA_KEY_MGMT_CROSS_AKM_ROAM)
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
#endif /* IEEE802_11_DEFS_H */
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 7a2ee32..e215762 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -682,4 +682,13 @@
*/
bool tls_connection_get_own_cert_used(struct tls_connection *conn);
+/**
+ * tls_register_cert_callback - Register a callback to retrieve certificates
+ * @cb: Callback object to register
+ */
+typedef ssize_t (*tls_get_certificate_cb)
+(void* ctx, const char* alias, uint8_t** value);
+
+void tls_register_cert_callback(tls_get_certificate_cb cb);
+
#endif /* TLS_H */
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index dc8a1b4..ab82e3d 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -126,9 +126,28 @@
}
#endif
+static int tls_openssl_ref_count = 0;
+static int tls_ex_idx_session = -1;
+
+struct tls_session_data {
+ struct dl_list list;
+ struct wpabuf *buf;
+};
+
+struct tls_context {
+ void (*event_cb)(void *ctx, enum tls_event ev,
+ union tls_event_data *data);
+ void *cb_ctx;
+ int cert_in_cb;
+ char *ocsp_stapling_response;
+ struct dl_list sessions; /* struct tls_session_data */
+};
+
+static struct tls_context *tls_global = NULL;
+static tls_get_certificate_cb certificate_callback_global = NULL;
+
#ifdef ANDROID
#include <openssl/pem.h>
-#include <keystore/keystore_get.h>
#include <log/log.h>
#include <log/log_event_list.h>
@@ -152,9 +171,11 @@
{
BIO *bio = NULL;
uint8_t *value = NULL;
- int length = keystore_get(alias, strlen(alias), &value);
- if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
- BIO_write(bio, value, length);
+ if (tls_global != NULL && certificate_callback_global != NULL) {
+ int length = (*certificate_callback_global)(tls_global->cb_ctx, alias, &value);
+ if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
+ BIO_write(bio, value, length);
+ }
free(value);
return bio;
}
@@ -229,26 +250,6 @@
#endif /* ANDROID */
-static int tls_openssl_ref_count = 0;
-static int tls_ex_idx_session = -1;
-
-struct tls_session_data {
- struct dl_list list;
- struct wpabuf *buf;
-};
-
-struct tls_context {
- void (*event_cb)(void *ctx, enum tls_event ev,
- union tls_event_data *data);
- void *cb_ctx;
- int cert_in_cb;
- char *ocsp_stapling_response;
- struct dl_list sessions; /* struct tls_session_data */
-};
-
-static struct tls_context *tls_global = NULL;
-
-
struct tls_data {
SSL_CTX *ssl;
unsigned int tls_session_lifetime;
@@ -6025,3 +6026,8 @@
return SSL_get_certificate(conn->ssl) != NULL;
return false;
}
+
+void tls_register_cert_callback(tls_get_certificate_cb cb)
+{
+ certificate_callback_global = cb;
+}
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 6bbf1ec..71d799d 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1251,12 +1251,12 @@
* 2 = both hunting-and-pecking loop and hash-to-element enabled
*/
int sae_pwe;
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
/**
* td_policy - Transition Disable Policy
*/
u32 td_policy;
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
};
enum hide_ssid {
@@ -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;
@@ -2598,9 +2599,9 @@
WPA_DRV_UPDATE_ASSOC_IES = BIT(0),
WPA_DRV_UPDATE_FILS_ERP_INFO = BIT(1),
WPA_DRV_UPDATE_AUTH_TYPE = BIT(2),
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
WPA_DRV_UPDATE_TD_POLICY = BIT(3),
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
};
/**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 1385edb..0568894 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -201,9 +201,9 @@
#endif /* CONFIG_MESH */
static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
u16 reason);
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
static int nl80211_set_td_policy(void *priv, u32 td_policy);
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
/* Converts nl80211_chan_width to a common format */
enum chan_width convert2width(int width)
@@ -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)) {
@@ -3313,7 +3328,7 @@
}
#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
static int wpa_cross_akm_key_mgmt_to_suites(unsigned int key_mgmt_suites, u32 suites[],
int max_suites)
{
@@ -3329,7 +3344,7 @@
return num_suites;
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
#ifdef CONFIG_DRIVER_NL80211_QCA
static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
@@ -6560,7 +6575,7 @@
os_free(mgmt);
}
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if (IS_CROSS_AKM_ROAM_KEY_MGMT(params->key_mgmt_suite)) {
int num_suites;
u32 suites[NL80211_MAX_NR_AKM_SUITES];
@@ -6575,7 +6590,7 @@
return -1;
}
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
if (params->req_handshake_offload &&
(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) {
wpa_printf(MSG_DEBUG, " * WANT_1X_4WAY_HS");
@@ -6638,13 +6653,13 @@
nl80211_put_fils_connect_params(drv, params, msg) != 0)
return -1;
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if (((params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
(params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE)) &&
#else
if ((wpa_key_mgmt_sae(params->key_mgmt_suite) ||
wpa_key_mgmt_sae(params->allowed_key_mgmts)) &&
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
(!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) &&
nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT))
return -1;
@@ -6693,13 +6708,13 @@
goto fail;
#ifdef CONFIG_SAE
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if (((params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
(params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE)) &&
#else
if ((wpa_key_mgmt_sae(params->key_mgmt_suite) ||
wpa_key_mgmt_sae(params->allowed_key_mgmts)) &&
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
nl80211_put_sae_pwe(msg, params->sae_pwe) < 0)
goto fail;
#endif /* CONFIG_SAE */
@@ -6807,13 +6822,13 @@
if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
return -1;
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if ((params->key_mgmt_suite & WPA_KEY_MGMT_SAE) ||
(params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE))
#else
if (wpa_key_mgmt_sae(params->key_mgmt_suite) ||
wpa_key_mgmt_sae(params->allowed_key_mgmts))
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
bss->use_nl_connect = 1;
else
bss->use_nl_connect = 0;
@@ -12740,7 +12755,7 @@
return 0;
/* Handle any connection param update here which might receive kernel handling in future */
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if (mask & WPA_DRV_UPDATE_TD_POLICY) {
ret = nl80211_set_td_policy(priv, params->td_policy);
if (ret) {
@@ -12750,7 +12765,7 @@
}
return ret;
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_CONNECT_PARAMS);
if (!msg)
@@ -12905,7 +12920,7 @@
}
#endif /* CONFIG_DPP */
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
static int nl80211_set_td_policy(void *priv, u32 td_policy)
{
struct i802_bss *bss = priv;
@@ -12934,7 +12949,7 @@
return ret;
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
#ifdef CONFIG_TESTING_OPTIONS
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..15664df 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;
@@ -2193,6 +2196,14 @@
os_free(hash_hex);
}
+ssize_t tls_certificate_callback(void* ctx, const char* alias, uint8_t** value) {
+ if (alias == NULL || ctx == NULL || value == NULL) return -1;
+ struct eap_sm *sm = (struct eap_sm*) ctx;
+ if (sm->eapol_cb && sm->eapol_cb->get_certificate) {
+ return sm->eapol_cb->get_certificate(sm->eapol_ctx, alias, value);
+ }
+ return -1;
+}
/**
* eap_peer_sm_init - Allocate and initialize EAP peer state machine
@@ -2236,6 +2247,7 @@
tlsconf.event_cb = eap_peer_sm_tls_event;
tlsconf.cb_ctx = sm;
tlsconf.cert_in_cb = conf->cert_in_cb;
+ tls_register_cert_callback(&tls_certificate_callback);
sm->ssl_ctx = tls_init(&tlsconf);
if (sm->ssl_ctx == NULL) {
wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
@@ -2816,6 +2828,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 +3110,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..b98e878 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
@@ -295,6 +304,16 @@
* @reason_string: Information to log about the event
*/
void (*notify_open_ssl_failure)(void *ctx, const char* reason_string);
+
+ /**
+ * get_certificate - Retrieve a certificate from the certificate store
+ * @ctx: eapol_ctx from eap_peer_sm_init() call
+ * @alias: key into the certificate key-value store
+ * @value: pointer reference - pointer to the retrieved certificate will
+ * be stored here on success
+ * Returns: size of the retrieved certificate or -1 on error
+ */
+ ssize_t (*get_certificate)(void* ctx, const char* alias, uint8_t** value);
};
/**
@@ -366,11 +385,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..a8ac6fd 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)
@@ -2105,6 +2112,17 @@
sm->ctx->open_ssl_failure_cb(sm->ctx->ctx, reason_string);
}
+static ssize_t
+eapol_sm_get_certificate(void *ctx, const char* alias, uint8_t** value)
+{
+ struct eapol_sm *sm = ctx;
+
+ if (sm->ctx->get_certificate_cb) {
+ return sm->ctx->get_certificate_cb(alias, value);
+ }
+ return -1;
+}
+
static const struct eapol_callbacks eapol_cb =
{
eapol_sm_get_config,
@@ -2118,6 +2136,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
@@ -2127,7 +2146,8 @@
#endif /* CONFIG_EAP_PROXY */
eapol_sm_set_anon_id,
eapol_sm_notify_eap_method_selected,
- eapol_sm_notify_open_ssl_failure
+ eapol_sm_notify_open_ssl_failure,
+ eapol_sm_get_certificate
};
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index bbe2b6f..fe34ec9 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;
@@ -328,6 +336,15 @@
* Returns: Whether the current session requires encryption
*/
bool (*encryption_required)(void *ctx);
+
+ /**
+ * get_certificate_cb - Retrieve a certificate from the certificate store
+ * @alias: key into the certificate key-value store
+ * @value: pointer reference - pointer to the retrieved certificate will
+ * be stored here on success
+ * Returns: size of the retrieved certificate or -1 on error
+ */
+ ssize_t (*get_certificate_cb)(const char* alias, uint8_t** value);
};
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..be79765 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -67,14 +67,14 @@
defaults: ["wpa_supplicant_cflags_defaults"],
srcs: [":wpa_supplicant_srcs"],
shared_libs: [
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
+ "android.system.keystore2-V1-ndk",
"libbase",
"libbinder_ndk",
"libc",
"libcrypto",
"libcutils",
"libkeystore-engine-wifi-hidl",
- "libkeystore-wifi-hidl",
"liblog",
"libnl",
"libssl",
@@ -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..33dabf3 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1791,7 +1791,7 @@
LOCAL_SHARED_LIBRARIES += $(LIB_SHARED_EAP_PROXY)
endif
ifeq ($(CONFIG_TLS), openssl)
-LOCAL_SHARED_LIBRARIES += libcrypto libssl libkeystore-wifi-hidl
+LOCAL_SHARED_LIBRARIES += libcrypto libssl
endif
# With BoringSSL we need libkeystore-engine in order to provide access to
@@ -1812,7 +1812,8 @@
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 += android.system.keystore2-V1-ndk
LOCAL_SHARED_LIBRARIES += libutils libbase
LOCAL_SHARED_LIBRARIES += libbinder_ndk
LOCAL_STATIC_LIBRARIES += libwpa_aidl
@@ -1877,6 +1878,7 @@
LOCAL_SRC_FILES := \
aidl/aidl.cpp \
aidl/aidl_manager.cpp \
+ aidl/certificate_utils.cpp \
aidl/iface_config_utils.cpp \
aidl/p2p_iface.cpp \
aidl/p2p_network.cpp \
@@ -1884,7 +1886,8 @@
aidl/sta_network.cpp \
aidl/supplicant.cpp
LOCAL_SHARED_LIBRARIES := \
- android.hardware.wifi.supplicant-V1-ndk \
+ android.hardware.wifi.supplicant-V2-ndk \
+ android.system.keystore2-V1-ndk \
libbinder_ndk \
libbase \
libutils \
diff --git a/wpa_supplicant/aidl/Android.bp b/wpa_supplicant/aidl/Android.bp
index 0785fe1..d7dcf97 100644
--- a/wpa_supplicant/aidl/Android.bp
+++ b/wpa_supplicant/aidl/Android.bp
@@ -33,9 +33,11 @@
defaults: ["wpa_supplicant_cflags_defaults"],
soc_specific: true,
shared_libs: [
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
+ "android.system.keystore2-V1-ndk",
"libbinder_ndk",
"libbase",
+ "libcrypto",
"libutils",
"liblog",
"libssl",
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index a7945cc..75050c1 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)
{
@@ -1033,3 +1063,11 @@
aidl_manager->notifyQosPolicyRequest(wpa_s, policies, num_policies);
}
+ssize_t wpas_aidl_get_certificate(const char* alias, uint8_t** value)
+{
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return -1;
+
+ return aidl_manager->getCertificate(alias, value);
+}
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
index 2f3c7a0..b0ad1f2 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);
@@ -142,6 +145,7 @@
void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
struct dscp_policy_data *policies, int num_policies);
+ ssize_t wpas_aidl_get_certificate(const char* alias, uint8_t** value);
#else // CONFIG_CTRL_IFACE_AIDL
static inline int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
{
@@ -171,6 +175,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)
@@ -185,7 +191,7 @@
static void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
{}
-void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+static void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
struct wpa_supplicant *wpa_s, const char *url)
{}
static void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
@@ -203,7 +209,8 @@
static void wpas_aidl_notify_p2p_device_found(
struct wpa_supplicant *wpa_s, const u8 *addr,
const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
- u8 peer_wfd_device_info_len)
+ u8 peer_wfd_device_info_lenconst, u8 *peer_wfd_r2_device_info,
+ u8 peer_wfd_r2_device_info_len)
{}
static void wpas_aidl_notify_p2p_device_lost(
struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
@@ -252,12 +259,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)
{}
+static 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)
@@ -272,20 +280,24 @@
{}
static void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
{}
-static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
{}
-void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_dpp_fail(struct wpa_supplicant *wpa_s)
{}
-void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
{}
-void wpas_aidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
{}
-void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s,
+ enum dpp_status_error status, const char *ssid,
+ const char *channel_list, unsigned short band_list[], int size)
{}
static void wpas_aidl_notify_pmk_cache_added(struct wpa_supplicant *wpas,
struct rsn_pmksa_cache_entry *pmksa_entry)
{}
-void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+static void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
{}
static void wpas_aidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
@@ -293,22 +305,22 @@
{}
static void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
{}
-void wpas_aidl_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency)
+static void wpas_aidl_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency)
{}
-void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+static void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
int depth, const char *subject,
const char *altsubject[],
int num_altsubject,
const char *cert_hash,
const struct wpabuf *cert)
{}
-void wpas_aidl_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
+static void wpas_aidl_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
const char *reason_string)
{}
-void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
+static void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
const char *reason_string)
{}
-void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
+static void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
const char *reason_string)
{}
static void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s) {}
@@ -316,6 +328,10 @@
struct dscp_policy_data *policies,
int num_policies)
{}
+static ssize_t wpas_aidl_get_certificate(const char* alias, uint8_t** value)
+{
+ return -1;
+}
#endif // CONFIG_CTRL_IFACE_AIDL
#ifdef _cplusplus
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 1791b2b..4833938 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,
@@ -2109,6 +2209,21 @@
}
/**
+ * Store the |INonStandardCertCallback| aidl object reference.
+ *
+ * @param callback Aidl reference of the |INonStandardCertCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::registerNonStandardCertCallbackAidlObject(
+ const std::shared_ptr<INonStandardCertCallback> &callback)
+{
+ if (callback == nullptr) return 1;
+ non_standard_cert_callback_ = callback;
+ return 0;
+}
+
+/**
* Add a new iface callback aidl object reference to our
* interface callback list.
*
@@ -2460,6 +2575,20 @@
std::placeholders::_1, wpa_s->dscp_req_dialog_token, qosPolicyData));
}
+ssize_t AidlManager::getCertificate(const char* alias, uint8_t** value) {
+ if (alias == nullptr || value == nullptr) {
+ wpa_printf(MSG_ERROR, "Null pointer argument was passed to getCertificate");
+ return -1;
+ }
+ if (auto cert = certificate_utils::getCertificate(alias, non_standard_cert_callback_)) {
+ *value = (uint8_t *) os_malloc(cert->size());
+ if (*value == nullptr) return -1;
+ os_memcpy(*value, cert->data(), cert->size());
+ return cert->size();
+ }
+ return -1;
+}
+
} // namespace supplicant
} // namespace wifi
} // namespace hardware
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index 1ed6899..e4af31a 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -16,6 +16,7 @@
#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.h>
#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.h>
+#include "certificate_utils.h"
#include "p2p_iface.h"
#include "p2p_network.h"
#include "rsn_supp/pmksa_cache.h"
@@ -61,6 +62,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 +128,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);
@@ -157,6 +163,7 @@
void notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
struct dscp_policy_data *policies,
int num_policies);
+ ssize_t getCertificate(const char* alias, uint8_t** value);
// Methods called from aidl objects.
void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
@@ -186,6 +193,8 @@
int addStaNetworkCallbackAidlObject(
const std::string &ifname, int network_id,
const std::shared_ptr<ISupplicantStaNetworkCallback> &callback);
+ int registerNonStandardCertCallbackAidlObject(
+ const std::shared_ptr<INonStandardCertCallback> &callback);
private:
AidlManager() = default;
@@ -273,6 +282,8 @@
const std::string,
std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>>
sta_network_callbacks_map_;
+ // NonStandardCertCallback registered by the client.
+ std::shared_ptr<INonStandardCertCallback> non_standard_cert_callback_;
};
// The aidl interface uses some values which are the same as internal ones to
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/certificate_utils.cpp b/wpa_supplicant/aidl/certificate_utils.cpp
new file mode 100644
index 0000000..79fe38b
--- /dev/null
+++ b/wpa_supplicant/aidl/certificate_utils.cpp
@@ -0,0 +1,196 @@
+/*
+ * WPA Supplicant - Certificate utils
+ * Copyright (c) 2022, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "certificate_utils.h"
+
+#define AT __func__ << ":" << __LINE__ << " "
+
+namespace ks2 = aidl::android::system::keystore2;
+namespace KMV1 = aidl::android::hardware::security::keymint;
+
+using aidl::android::hardware::wifi::supplicant::INonStandardCertCallback;
+
+namespace {
+
+constexpr const int64_t KS2_NAMESPACE_WIFI = 102;
+
+constexpr const char kKeystore2ServiceName[] = "android.system.keystore2.IKeystoreService/default";
+
+const std::string keystore2_grant_id_prefix("ks2_keystore-engine_grant_id:");
+
+ks2::KeyDescriptor mkKeyDescriptor(const std::string& alias) {
+ // If the key_id starts with the grant id prefix, we parse the following string as numeric
+ // grant id. We can then use the grant domain without alias to load the designated key.
+ if (::android::base::StartsWith(alias, keystore2_grant_id_prefix)) {
+ std::stringstream s(alias.substr(keystore2_grant_id_prefix.size()));
+ uint64_t tmp;
+ s >> std::hex >> tmp;
+ if (s.fail() || !s.eof()) {
+ wpa_printf(MSG_ERROR, "Couldn't parse grant name: %s", alias.c_str());
+ }
+ return {
+ .domain = ks2::Domain::GRANT,
+ .nspace = static_cast<int64_t>(tmp),
+ .alias = std::nullopt,
+ .blob = std::nullopt,
+ };
+ } else {
+ return {
+ .domain = ks2::Domain::SELINUX,
+ .nspace = KS2_NAMESPACE_WIFI,
+ .alias = alias,
+ .blob = std::nullopt,
+ };
+ }
+}
+
+// Helper method to convert certs in DER format to PEM format required by
+// openssl library used by supplicant. If boringssl cannot parse the input as one or more
+// X509 certificates in DER encoding, this function returns the input as-is. The assumption in
+// that case is that either the `cert_bytes` is already PEM encoded, or `cert_bytes` is something
+// completely different that was intentionally installed by the Wi-Fi subsystem and it must not
+// be changed here.
+// If any error occurs during PEM encoding, this function returns std::nullopt and logs an error.
+std::optional<std::vector<uint8_t>> convertDerCertToPemOrPassthrough(
+ const std::vector<uint8_t>& cert_bytes) {
+ // If cert_bytes is a DER encoded X509 certificate, it must be reencoded as PEM, because
+ // wpa_supplicant only understand PEM. Otherwise the cert_bytes are returned as is.
+ const uint8_t* cert_current = cert_bytes.data();
+ const uint8_t* cert_end = cert_current + cert_bytes.size();
+ bssl::UniquePtr<BIO> pem_bio(BIO_new(BIO_s_mem()));
+ while (cert_current < cert_end) {
+ auto cert =
+ bssl::UniquePtr<X509>(d2i_X509(nullptr, &cert_current, cert_end - cert_current));
+ // If part of the bytes cannot be parsed as X509 DER certificate, the original blob
+ // shall be returned as-is.
+ if (!cert) {
+ wpa_printf(MSG_WARNING, "Could not parse DER X509 cert from buffer. Returning blob as is.");
+ return cert_bytes;
+ }
+
+ if (!PEM_write_bio_X509(pem_bio.get(), cert.get())) {
+ wpa_printf(MSG_ERROR, "Could not convert cert to PEM format.");
+ return std::nullopt;
+ }
+ }
+
+ const uint8_t* pem_bytes;
+ size_t pem_len;
+ if (!BIO_mem_contents(pem_bio.get(), &pem_bytes, &pem_len)) {
+ wpa_printf(MSG_ERROR, "Could not extract pem_bytes from BIO.");
+ return std::nullopt;
+ }
+ return {{pem_bytes, pem_bytes + pem_len}};
+}
+
+std::optional<std::vector<uint8_t>> getKeystore2Cert(const std::string& key) {
+ ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(kKeystore2ServiceName));
+ auto keystore2 = ks2::IKeystoreService::fromBinder(keystoreBinder);
+
+ if (!keystore2) {
+ wpa_printf(MSG_WARNING, "Unable to connect to Keystore 2.");
+ return {};
+ }
+
+ bool ca_cert = false;
+ std::string alias = key.c_str();
+ if (::android::base::StartsWith(alias, "CACERT_")) {
+ alias = alias.substr(7);
+ ca_cert = true;
+ } else if (::android::base::StartsWith(alias, "USRCERT_")) {
+ alias = alias.substr(8);
+ }
+
+ ks2::KeyDescriptor descriptor = mkKeyDescriptor(alias);
+
+ // If the key_id starts with the grant id prefix, we parse the following string as numeric
+ // grant id. We can then use the grant domain without alias to load the designated key.
+ if (::android::base::StartsWith(alias, keystore2_grant_id_prefix)) {
+ std::stringstream s(alias.substr(keystore2_grant_id_prefix.size()));
+ uint64_t tmp;
+ s >> std::hex >> tmp;
+ if (s.fail() || !s.eof()) {
+ wpa_printf(MSG_ERROR, "Couldn't parse grant name: %s", alias.c_str());
+ }
+ descriptor.nspace = static_cast<int64_t>(tmp);
+ descriptor.domain = ks2::Domain::GRANT;
+ descriptor.alias = std::nullopt;
+ }
+
+ ks2::KeyEntryResponse response;
+ auto rc = keystore2->getKeyEntry(descriptor, &response);
+ if (!rc.isOk()) {
+ if (rc.getServiceSpecificError() != int32_t(ks2::ResponseCode::KEY_NOT_FOUND)) {
+ wpa_printf(MSG_WARNING, "Entry not found in Keystore 2.");
+ } else {
+ wpa_printf(MSG_WARNING, "Keystore 2 getKeyEntry failed error: %s", rc.getDescription().c_str());
+ }
+ return {};
+ }
+
+ if (ca_cert && response.metadata.certificateChain) {
+ return std::move(*response.metadata.certificateChain);
+ } else if (!ca_cert && response.metadata.certificate) {
+ return std::move(*response.metadata.certificate);
+ } else {
+ wpa_printf(MSG_WARNING, "No %s certificate found.", (ca_cert ? "CA" : "client"));
+ return {};
+ }
+}
+
+std::optional<std::vector<uint8_t>> getNonStandardCert(const std::string& alias,
+ const std::shared_ptr<INonStandardCertCallback> &non_standard_callback) {
+ if (non_standard_callback == nullptr) {
+ wpa_printf(MSG_ERROR, "Non-standard cert callback is not available");
+ return std::nullopt;
+ }
+ std::vector<uint8_t> blob;
+ const auto& status = non_standard_callback->getBlob(alias, &blob);
+ if (!status.isOk()) {
+ wpa_printf(MSG_ERROR, "Cert callback error, code=%d",
+ status.getServiceSpecificError());
+ return std::nullopt;
+ }
+ return blob;
+}
+
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace certificate_utils {
+
+std::optional<std::vector<uint8_t>> getCertificate(const std::string& alias,
+ const std::shared_ptr<INonStandardCertCallback> &non_standard_callback) {
+ std::vector<uint8_t> cert;
+ if (auto ks2_cert = getKeystore2Cert(alias)) {
+ cert = std::move(*ks2_cert);
+ } else if (auto blob = getNonStandardCert(alias, non_standard_callback)) {
+ cert = std::move(*blob);
+ } else {
+ wpa_printf(MSG_ERROR, "Failed to get certificate.");
+ return std::nullopt;
+ }
+
+ if (auto result_cert = convertDerCertToPemOrPassthrough(cert)) {
+ return result_cert;
+ } else {
+ wpa_printf(MSG_ERROR, "Conversion to PEM failed.");
+ return std::nullopt;
+ }
+}
+
+} // namespace certificate_utils
+} // namespace supplicant
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wpa_supplicant/aidl/certificate_utils.h b/wpa_supplicant/aidl/certificate_utils.h
new file mode 100644
index 0000000..09da74b
--- /dev/null
+++ b/wpa_supplicant/aidl/certificate_utils.h
@@ -0,0 +1,40 @@
+/*
+ * WPA Supplicant - Certificate utils
+ * Copyright (c) 2022, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.h>
+#include <aidl/android/system/keystore2/IKeystoreService.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
+#include <android-base/strings.h>
+#include <android/binder_manager.h>
+#include <openssl/base.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <vector>
+
+extern "C"
+{
+#include "utils/common.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace certificate_utils {
+ std::optional<std::vector<uint8_t>> getCertificate(const std::string& alias,
+ const std::shared_ptr<INonStandardCertCallback> &non_standard_callback);
+} // namespace certificate_utils
+} // namespace supplicant
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
index ce945a4..c8056f0 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) {
@@ -1048,6 +1051,9 @@
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
p2ps_provision* prov_param;
const char* config_method_str = nullptr;
+ if (peer_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
switch (provision_method) {
case WpsProvisionMethod::PBC:
config_method_str = kConfigMethodStrPbc;
@@ -1087,6 +1093,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 +1108,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 +1133,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))) {
@@ -1182,6 +1197,10 @@
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+ if (peer_address.size() != ETH_ALEN) {
+ return {std::vector<uint8_t>(),
+ createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
const struct p2p_peer_info* info =
p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
if (!info) {
@@ -1204,6 +1223,10 @@
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+ if (peer_address.size() != ETH_ALEN) {
+ return {static_cast<P2pGroupCapabilityMask>(0),
+ createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
const struct p2p_peer_info* info =
p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
if (!info) {
@@ -1284,6 +1307,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 +1356,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 +1407,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 +1442,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);
}
@@ -1629,6 +1664,10 @@
// The rest is for group join.
wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
wpas_p2p_stop_find(wpa_s);
+ if (peer_address.size() != ETH_ALEN) {
+ return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+ "Peer address is invalid.");
+ }
if (joinGroup(wpa_s, peer_address.data(), ssid, passphrase, freq)) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
"Failed to start scan.");
@@ -1732,6 +1771,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..086c0a6 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,40 @@
&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
}
+::ndk::ScopedAStatus StaIface::getSignalPollResults(
+ std::vector<SignalPollResult> *results)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_UNKNOWN,
+ &StaIface::getSignalPollResultsInternal, results);
+}
+
+::ndk::ScopedAStatus StaIface::addQosPolicyRequestForScs(
+ const std::vector<QosPolicyScsData>& in_qosPolicyData,
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_UNKNOWN,
+ &StaIface::addQosPolicyRequestForScsInternal, _aidl_return, in_qosPolicyData);
+}
+
+::ndk::ScopedAStatus StaIface::removeQosPolicyForScs(
+ const std::vector<uint8_t>& in_scsPolicyIds,
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_UNKNOWN,
+ &StaIface::removeQosPolicyForScsInternal, _aidl_return, in_scsPolicyIds);
+}
+
+::ndk::ScopedAStatus StaIface::removeAllQosPoliciesForScs(
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_UNKNOWN,
+ &StaIface::removeAllQosPoliciesForScsInternal, _aidl_return);
+}
+
std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
{
return {ifname_, ndk::ScopedAStatus::ok()};
@@ -986,6 +1021,9 @@
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
int ret;
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
const u8 *peer = mac_address.data();
if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
@@ -1003,6 +1041,9 @@
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
int ret;
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
const u8 *peer = mac_address.data();
if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
!(wpa_s->conf->tdls_external_control)) {
@@ -1022,6 +1063,9 @@
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
int ret;
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
const u8 *peer = mac_address.data();
if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
!(wpa_s->conf->tdls_external_control)) {
@@ -1058,6 +1102,9 @@
static_cast<std::underlying_type<
Hs20AnqpSubtypes>::type>(type));
}
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
if (anqp_send_req(
wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
@@ -1072,6 +1119,9 @@
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
if (anqp_send_req(
wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
@@ -1084,6 +1134,9 @@
const std::vector<uint8_t> &mac_address, const std::string &file_name)
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (mac_address.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
wpa_s->fetch_osu_icon_in_progress = 0;
if (hs20_anqp_send_req(
wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
@@ -1185,6 +1238,10 @@
const std::vector<uint8_t> &code)
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ //2-Character alphanumeric country code
+ if (code.size() != 2) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
ndk::ScopedAStatus status = doOneArgDriverCommand(
wpa_s, kSetCountryCode,
std::string(std::begin(code), std::end(code)));
@@ -1206,6 +1263,9 @@
const std::vector<uint8_t> &bssid, const std::string &pin)
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (bssid.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
@@ -1216,6 +1276,9 @@
const std::vector<uint8_t> &bssid)
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (bssid.size() != ETH_ALEN) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
const uint8_t *bssid_addr =
is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
@@ -1238,6 +1301,9 @@
const std::vector<uint8_t> &bssid)
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ 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 =
@@ -1609,6 +1675,9 @@
}
cmd += " chan=" + listen_channel_str;
+ if (mac_address.size() != ETH_ALEN) {
+ return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+ }
cmd += " mac=";
for (int i = 0;i < 6;i++) {
snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
@@ -1747,7 +1816,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 +1849,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 +1891,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 +2010,97 @@
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()};
+}
+
+
+std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+StaIface::addQosPolicyRequestForScsInternal(const std::vector<QosPolicyScsData>& qosPolicyData)
+{
+ return {std::vector<QosPolicyScsRequestStatus>(),
+ createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+}
+
+std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+StaIface::removeQosPolicyForScsInternal(const std::vector<uint8_t>& scsPolicyIds)
+{
+ return {std::vector<QosPolicyScsRequestStatus>(),
+ createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+}
+
+std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+StaIface::removeAllQosPoliciesForScsInternal()
+{
+ return {std::vector<QosPolicyScsRequestStatus>(),
+ createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+}
+
/**
* 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..88c6e45 100644
--- a/wpa_supplicant/aidl/sta_iface.h
+++ b/wpa_supplicant/aidl/sta_iface.h
@@ -157,6 +157,16 @@
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;
+ ::ndk::ScopedAStatus addQosPolicyRequestForScs(
+ const std::vector<QosPolicyScsData>& in_qosPolicyData,
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return) override;
+ ::ndk::ScopedAStatus removeQosPolicyForScs(
+ const std::vector<uint8_t>& in_scsPolicyIds,
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return) override;
+ ::ndk::ScopedAStatus removeAllQosPoliciesForScs(
+ std::vector<QosPolicyScsRequestStatus>* _aidl_return) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -261,6 +271,17 @@
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();
+ std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+ addQosPolicyRequestForScsInternal(
+ const std::vector<QosPolicyScsData>& qosPolicyData);
+ std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+ removeQosPolicyForScsInternal(
+ const std::vector<uint8_t>& scsPolicyIds);
+ std::pair<std::vector<QosPolicyScsRequestStatus>, ndk::ScopedAStatus>
+ removeAllQosPoliciesForScsInternal();
+
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/aidl/supplicant.cpp b/wpa_supplicant/aidl/supplicant.cpp
index 799790b..74602e4 100644
--- a/wpa_supplicant/aidl/supplicant.cpp
+++ b/wpa_supplicant/aidl/supplicant.cpp
@@ -239,6 +239,14 @@
&Supplicant::registerCallbackInternal, in_callback);
}
+::ndk::ScopedAStatus Supplicant::registerNonStandardCertCallback(
+ const std::shared_ptr<INonStandardCertCallback>& in_callback)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &Supplicant::registerNonStandardCertCallbackInternal, in_callback);
+}
+
::ndk::ScopedAStatus Supplicant::setDebugParams(
DebugLevel in_level, bool in_showTimestamp,
bool in_showKeys)
@@ -547,6 +555,17 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Supplicant::registerNonStandardCertCallbackInternal(
+ const std::shared_ptr<INonStandardCertCallback>& callback)
+{
+ AidlManager* aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager ||
+ aidl_manager->registerNonStandardCertCallbackAidlObject(callback)) {
+ return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Supplicant::setDebugParamsInternal(
DebugLevel level, bool show_timestamp, bool show_keys)
{
diff --git a/wpa_supplicant/aidl/supplicant.h b/wpa_supplicant/aidl/supplicant.h
index cbe9a67..12b9299 100644
--- a/wpa_supplicant/aidl/supplicant.h
+++ b/wpa_supplicant/aidl/supplicant.h
@@ -64,6 +64,8 @@
std::vector<IfaceInfo>* _aidl_return) override;
::ndk::ScopedAStatus registerCallback(
const std::shared_ptr<ISupplicantCallback>& in_callback) override;
+ ::ndk::ScopedAStatus registerNonStandardCertCallback(
+ const std::shared_ptr<INonStandardCertCallback>& in_callback) override;
::ndk::ScopedAStatus setDebugParams(
DebugLevel in_level, bool in_showTimestamp, bool in_showKeys) override;
::ndk::ScopedAStatus getDebugLevel(DebugLevel* _aidl_return) override;
@@ -82,11 +84,13 @@
getP2pInterfaceInternal(const std::string& name);
std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
getStaInterfaceInternal(const std::string& name);
-
+
ndk::ScopedAStatus removeInterfaceInternal(const IfaceInfo& iface_info);
std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus> listInterfacesInternal();
ndk::ScopedAStatus registerCallbackInternal(
const std::shared_ptr<ISupplicantCallback>& callback);
+ ndk::ScopedAStatus registerNonStandardCertCallbackInternal(
+ const std::shared_ptr<INonStandardCertCallback>& callback);
ndk::ScopedAStatus setDebugParamsInternal(
DebugLevel level, bool show_timestamp, bool show_keys);
ndk::ScopedAStatus setConcurrencyPriorityInternal(IfaceType type);
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..d13a8d0 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -29,7 +29,7 @@
#include "scan.h"
#include "notify.h"
#include "dpp_supplicant.h"
-#include "aidl.h"
+#include "aidl/aidl.h"
static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
@@ -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..6c82b66 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1396,9 +1396,9 @@
if ((wpa_s->conf->sae_pwe == 1 || is_6ghz_freq(bss->freq) ||
ssid->sae_password_id) &&
wpa_s->conf->sae_pwe != 3 && wpa_key_mgmt_sae(ssid->key_mgmt) &&
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
!(wpa_key_mgmt_wpa_psk_no_sae(ssid->key_mgmt)) &&
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -2998,9 +2998,9 @@
const u8 *p;
u8 bssid[ETH_ALEN];
bool bssid_known;
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
struct wpa_ie_data ie;
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
@@ -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);
@@ -3127,7 +3128,7 @@
if (!found_x && data->assoc_info.req_ies)
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
/* The WPA/RSN IE has been updated at this point. Since the Firmware could have roamed
* to a different security type, update the current supplicant configuration to use the AKM
* and pairwise suites from the assoc IE passed by the driver.
@@ -3171,7 +3172,7 @@
// TODO: Notify the framework about security type change b/230766005
}
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
#ifdef CONFIG_FILS
#ifdef CONFIG_SME
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..bb2c0b7 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -24,7 +24,7 @@
#include "p2p_supplicant.h"
#include "sme.h"
#include "notify.h"
-#include "aidl.h"
+#include "aidl/aidl.h"
int wpas_notify_supplicant_initialized(struct wpa_global *global)
{
@@ -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)
{
@@ -1335,3 +1352,8 @@
wpas_aidl_notify_frequency_changed(wpa_s, frequency);
}
+
+ssize_t wpas_get_certificate(const char *alias, uint8_t** value)
+{
+ return wpas_aidl_get_certificate(alias, value);
+}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 996be84..9a818ef 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);
@@ -218,5 +221,6 @@
void wpas_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
struct dscp_policy_data *policies, int num_policies);
void wpas_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency);
+ssize_t wpas_get_certificate(const char *alias, uint8_t** value);
#endif /* NOTIFY_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 56dd5b9..7d896f4 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2031,11 +2031,12 @@
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 0);
}
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
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");
@@ -2044,7 +2045,7 @@
if (wpa_key_mgmt_cross_akm(wpa_s->key_mgmt) &&
!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
wpas_update_allowed_key_mgmt(wpa_s, ssid);
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
return 0;
}
@@ -4069,7 +4070,7 @@
#endif /* CONFIG_WEP */
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
((params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
(params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK))) {
#else
@@ -4077,7 +4078,7 @@
params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
(params.allowed_key_mgmts &
(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK)))) {
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
params.passphrase = ssid->passphrase;
if (ssid->psk_set)
params.psk = ssid->psk;
@@ -4101,14 +4102,14 @@
else
params.req_key_mgmt_offload = 1;
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
if (((params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
#else
if ((wpa_key_mgmt_wpa_psk_no_sae(params.key_mgmt_suite) ||
wpa_key_mgmt_wpa_psk_no_sae(params.allowed_key_mgmts)) &&
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
ssid->psk_set)
params.psk = ssid->psk;
}
@@ -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..556f9cf 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)
@@ -1197,6 +1203,12 @@
wpa_sm_pmf_enabled(wpa_s->wpa);
}
+static ssize_t wpa_supplicant_get_certificate_cb(
+ const char* alias, uint8_t** value)
+{
+ return wpas_get_certificate(alias, value);
+}
+
#endif /* IEEE8021X_EAPOL */
@@ -1238,6 +1250,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;
@@ -1245,6 +1258,7 @@
ctx->set_anon_id = wpa_supplicant_set_anon_id;
ctx->eap_method_selected_cb = wpa_supplicant_eap_method_selected_cb;
ctx->open_ssl_failure_cb = wpa_supplicant_open_ssl_failure_cb;
+ ctx->get_certificate_cb = wpa_supplicant_get_certificate_cb;
ctx->encryption_required = wpas_encryption_required;
ctx->cb_ctx = wpa_s;
wpa_s->eapol = eapol_sm_init(ctx);
@@ -1389,7 +1403,7 @@
changed = 1;
}
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
/* driver call for transition disable */
{
struct wpa_driver_associate_params params;
@@ -1398,7 +1412,7 @@
params.td_policy = bitmap;
wpa_drv_update_connect_params(wpa_s, ¶ms, WPA_DRV_UPDATE_TD_POLICY);
}
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
wpas_notify_transition_disable(wpa_s, ssid, bitmap);