hostapd: Add SAE Support
Bug: 142752869
Test: Manual test, fake test code to enable SAE and SAE transition mode,
Client which support SAE will identify SAP enabled in SAE mode.
In transition mode, the non-support SAE client(likes P16 devices) can connect succeed.
But Client which support SAE (likes P18 devices) will fail to connect since current Pixel
driver not support the SAE connection. But SAP beacon show it secured by SAE which P18
will show correct security type (i.e. SAE) in wifi scan list.
Change-Id: Ia62e1aaed277a5ad01dd3b8ee01b8c7eb40f1eb7
diff --git a/hostapd/hidl/1.2/hostapd.cpp b/hostapd/hidl/1.2/hostapd.cpp
index b40087a..8922f68 100644
--- a/hostapd/hidl/1.2/hostapd.cpp
+++ b/hostapd/hidl/1.2/hostapd.cpp
@@ -203,29 +203,22 @@
return 0;
}
+bool validatePassphrase(int passphrase_len, int min_len, int max_len)
+{
+ if (min_len != -1 && passphrase_len < min_len) return false;
+ if (max_len != -1 && passphrase_len > max_len) return false;
+ return true;
+}
+
std::string CreateHostapdConfig(
const IHostapd::IfaceParams& iface_params,
const IHostapd::NetworkParams& nw_params)
{
- if (nw_params.ssid.size() >
+ if (nw_params.V1_0.ssid.size() >
static_cast<uint32_t>(
IHostapd::ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
wpa_printf(
- MSG_ERROR, "Invalid SSID size: %zu", nw_params.ssid.size());
- return "";
- }
- if ((nw_params.encryptionType != IHostapd::EncryptionType::NONE) &&
- (nw_params.pskPassphrase.size() <
- static_cast<uint32_t>(
- IHostapd::ParamSizeLimits::
- WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
- nw_params.pskPassphrase.size() >
- static_cast<uint32_t>(
- IHostapd::ParamSizeLimits::
- WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
- wpa_printf(
- MSG_ERROR, "Invalid psk passphrase size: %zu",
- nw_params.pskPassphrase.size());
+ MSG_ERROR, "Invalid SSID size: %zu", nw_params.V1_0.ssid.size());
return "";
}
@@ -233,7 +226,7 @@
std::stringstream ss;
ss << std::hex;
ss << std::setfill('0');
- for (uint8_t b : nw_params.ssid) {
+ for (uint8_t b : nw_params.V1_0.ssid) {
ss << std::setw(2) << static_cast<unsigned int>(b);
}
const std::string ssid_as_string = ss.str();
@@ -245,18 +238,67 @@
// no security params
break;
case IHostapd::EncryptionType::WPA:
+ if (!validatePassphrase(
+ nw_params.passphrase.size(),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+ return "";
+ }
encryption_config_as_string = StringPrintf(
"wpa=3\n"
"wpa_pairwise=TKIP CCMP\n"
"wpa_passphrase=%s",
- nw_params.pskPassphrase.c_str());
+ nw_params.passphrase.c_str());
break;
case IHostapd::EncryptionType::WPA2:
+ if (!validatePassphrase(
+ nw_params.passphrase.size(),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+ return "";
+ }
encryption_config_as_string = StringPrintf(
"wpa=2\n"
"rsn_pairwise=CCMP\n"
"wpa_passphrase=%s",
- nw_params.pskPassphrase.c_str());
+ nw_params.passphrase.c_str());
+ break;
+ case IHostapd::EncryptionType::WPA3_SAE_TRANSITION:
+ if (!validatePassphrase(
+ nw_params.passphrase.size(),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+ static_cast<uint32_t>(IHostapd::ParamSizeLimits::
+ WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+ return "";
+ }
+ encryption_config_as_string = StringPrintf(
+ "wpa=2\n"
+ "rsn_pairwise=CCMP\n"
+ "wpa_key_mgmt=WPA-PSK SAE\n"
+ "ieee80211w=1\n"
+ "sae_require_mfp=1\n"
+ "wpa_passphrase=%s\n"
+ "sae_password=%s",
+ nw_params.passphrase.c_str(),
+ nw_params.passphrase.c_str());
+ break;
+ case IHostapd::EncryptionType::WPA3_SAE:
+ if (!validatePassphrase(nw_params.passphrase.size(), 1, -1)) {
+ return "";
+ }
+ encryption_config_as_string = StringPrintf(
+ "wpa=2\n"
+ "rsn_pairwise=CCMP\n"
+ "wpa_key_mgmt=SAE\n"
+ "ieee80211w=2\n"
+ "sae_require_mfp=2\n"
+ "sae_password=%s",
+ nw_params.passphrase.c_str());
break;
default:
wpa_printf(MSG_ERROR, "Unknown encryption type");
@@ -373,7 +415,7 @@
iface_params.V1_1.V1_0.hwModeParams.enable80211AC ? 1 : 0,
he_params_as_string.c_str(),
hw_mode_as_string.c_str(), ht_cap_vht_oper_chwidth_as_string.c_str(),
- nw_params.isHidden ? 1 : 0, encryption_config_as_string.c_str());
+ nw_params.V1_0.isHidden ? 1 : 0, encryption_config_as_string.c_str());
}
// hostapd core functions accept "C" style function pointers, so use global
@@ -410,7 +452,7 @@
Return<void> Hostapd::addAccessPoint(
const V1_0::IHostapd::IfaceParams& iface_params,
- const NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
+ const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
{
return call(
this, &Hostapd::addAccessPointInternal, _hidl_cb, iface_params,
@@ -419,7 +461,7 @@
Return<void> Hostapd::addAccessPoint_1_1(
const V1_1::IHostapd::IfaceParams& iface_params,
- const NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
+ const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
{
return call(
this, &Hostapd::addAccessPointInternal_1_1, _hidl_cb, iface_params,
@@ -474,14 +516,14 @@
V1_0::HostapdStatus Hostapd::addAccessPointInternal(
const V1_0::IHostapd::IfaceParams& iface_params,
- const NetworkParams& nw_params)
+ const V1_0::IHostapd::NetworkParams& nw_params)
{
return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
}
V1_0::HostapdStatus Hostapd::addAccessPointInternal_1_1(
const V1_1::IHostapd::IfaceParams& iface_params,
- const NetworkParams& nw_params)
+ const V1_1::IHostapd::NetworkParams& nw_params)
{
return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
}
diff --git a/hostapd/hidl/1.2/hostapd.h b/hostapd/hidl/1.2/hostapd.h
index 9a7e8b1..ca6c32e 100644
--- a/hostapd/hidl/1.2/hostapd.h
+++ b/hostapd/hidl/1.2/hostapd.h
@@ -78,7 +78,7 @@
const V1_0::IHostapd::NetworkParams& nw_params);
V1_2::HostapdStatus addAccessPointInternal_1_2(
const V1_2::IHostapd::IfaceParams& IfaceParams,
- const V1_0::IHostapd::NetworkParams& nw_params);
+ const V1_2::IHostapd::NetworkParams& nw_params);
V1_0::HostapdStatus removeAccessPointInternal(const std::string& iface_name);
V1_0::HostapdStatus registerCallbackInternal(
const sp<V1_1::IHostapdCallback>& callback);