From 4a1a1513fcd2846f914f3134eb8db81e59073a2c Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Mon, 15 Oct 2018 16:14:04 -0700 Subject: opt/net/wifi: Add support for WPA3 and OWE Add support for WPA3-Personal (SAE), WPA3-Enterprise (SuiteB) and OWE (Enhanced Open). Changes include new types and new methods. Bug: 112195778 Test: atest com.android.server.wifi Change-Id: I5c1520bd951cd4b6110f573e3522073dec6e910a --- service/Android.mk | 1 + .../android/server/wifi/ScanResultMatchInfo.java | 27 +- .../android/server/wifi/SupplicantStaIfaceHal.java | 49 +- .../server/wifi/SupplicantStaNetworkHal.java | 650 ++++++++++++++++++--- .../com/android/server/wifi/WifiConfigManager.java | 12 + .../android/server/wifi/WifiConfigurationUtil.java | 40 +- .../java/com/android/server/wifi/WifiMetrics.java | 12 +- .../java/com/android/server/wifi/WifiNative.java | 3 +- .../server/wifi/util/InformationElementUtil.java | 62 +- .../android/server/wifi/util/ScanResultUtil.java | 41 +- .../java/com/android/server/wifi/util/XmlUtil.java | 18 + 11 files changed, 825 insertions(+), 90 deletions(-) (limited to 'service') diff --git a/service/Android.mk b/service/Android.mk index aaa81afb9..d336b7bbd 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -69,6 +69,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ android.hardware.wifi.hostapd-V1.1-java \ android.hardware.wifi.supplicant-V1.0-java \ android.hardware.wifi.supplicant-V1.1-java \ + android.hardware.wifi.supplicant-V1.2-java \ ksoap2 \ libnanohttpd diff --git a/service/java/com/android/server/wifi/ScanResultMatchInfo.java b/service/java/com/android/server/wifi/ScanResultMatchInfo.java index 72fab6bc0..4f5f9ddfa 100644 --- a/service/java/com/android/server/wifi/ScanResultMatchInfo.java +++ b/service/java/com/android/server/wifi/ScanResultMatchInfo.java @@ -34,13 +34,19 @@ public class ScanResultMatchInfo { public static final int NETWORK_TYPE_WEP = 1; public static final int NETWORK_TYPE_PSK = 2; public static final int NETWORK_TYPE_EAP = 3; + public static final int NETWORK_TYPE_SAE = 4; + public static final int NETWORK_TYPE_EAP_SUITE_B = 5; + public static final int NETWORK_TYPE_OWE = 6; @Retention(SOURCE) @IntDef(prefix = { "NETWORK_TYPE_" }, value = { NETWORK_TYPE_OPEN, NETWORK_TYPE_WEP, NETWORK_TYPE_PSK, - NETWORK_TYPE_EAP + NETWORK_TYPE_EAP, + NETWORK_TYPE_SAE, + NETWORK_TYPE_EAP_SUITE_B, + NETWORK_TYPE_OWE }) public @interface NetworkType {} @@ -57,12 +63,18 @@ public class ScanResultMatchInfo { * Fetch network type from network configuration. */ public static @NetworkType int getNetworkType(WifiConfiguration config) { - if (WifiConfigurationUtil.isConfigForPskNetwork(config)) { + if (WifiConfigurationUtil.isConfigForSaeNetwork(config)) { + return NETWORK_TYPE_SAE; + } else if (WifiConfigurationUtil.isConfigForPskNetwork(config)) { return NETWORK_TYPE_PSK; } else if (WifiConfigurationUtil.isConfigForEapNetwork(config)) { return NETWORK_TYPE_EAP; + } else if (WifiConfigurationUtil.isConfigForEapSuiteBNetwork(config)) { + return NETWORK_TYPE_EAP_SUITE_B; } else if (WifiConfigurationUtil.isConfigForWepNetwork(config)) { return NETWORK_TYPE_WEP; + } else if (WifiConfigurationUtil.isConfigForOweNetwork(config)) { + return NETWORK_TYPE_OWE; } else if (WifiConfigurationUtil.isConfigForOpenNetwork(config)) { return NETWORK_TYPE_OPEN; } @@ -83,16 +95,23 @@ public class ScanResultMatchInfo { * Fetch network type from scan result. */ public static @NetworkType int getNetworkType(ScanResult scanResult) { - if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) { + if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { + return NETWORK_TYPE_SAE; + } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) { return NETWORK_TYPE_PSK; + } else if (ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { + return NETWORK_TYPE_EAP_SUITE_B; } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { return NETWORK_TYPE_EAP; } else if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) { return NETWORK_TYPE_WEP; + } else if (ScanResultUtil.isScanResultForOweNetwork(scanResult)) { + return NETWORK_TYPE_OWE; } else if (ScanResultUtil.isScanResultForOpenNetwork(scanResult)) { return NETWORK_TYPE_OPEN; + } else { + throw new IllegalArgumentException("Invalid ScanResult: " + scanResult); } - throw new IllegalArgumentException("Invalid ScanResult: " + scanResult); } /** diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java index ff7c1d238..04959b24e 100644 --- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java +++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java @@ -15,9 +15,14 @@ */ package com.android.server.wifi; +import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B; + import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork; import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName; -import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability; +import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType + .ANQPIPAddrAvailability; import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm; import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium; import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName; @@ -33,12 +38,11 @@ import android.hardware.wifi.supplicant.V1_0.ISupplicantIface; import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork; import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface; import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; -import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason; -import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; import android.hardware.wifi.supplicant.V1_0.IfaceType; import android.hardware.wifi.supplicant.V1_0.SupplicantStatus; import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods; +import android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; import android.net.IpConfiguration; @@ -2737,4 +2741,43 @@ public class SupplicantStaIfaceHal { private static void loge(String s) { Log.e(TAG, s); } + + /** + * Returns a bitmask of advanced key management capabilities: WPA3 SAE/SUITE B and OWE + * Bitmask used is: + * - WIFI_FEATURE_WPA3_SAE + * - WIFI_FEATURE_WPA3_SUITE_B + * - WIFI_FEATURE_OWE + */ + public int getAdvancedKeyMgmtCapabilities( + @NonNull String ifaceName) { + final String methodStr = "getAdvancedKeyMgmtCapabilities"; + + synchronized (mLock) { + SupplicantStaNetworkHal networkHal = getCurrentNetworkRemoteHandle(ifaceName); + if (networkHal == null) { + Log.e(TAG, "Can't call " + methodStr + ", SupplicantStaNetwork is null"); + return 0; + } + + int capabilities = networkHal.getKeyMgmtCapabilities(); + int advancedCapabilities = 0; + + if ((capabilities & ISupplicantStaNetwork.KeyMgmtMask.SAE) != 0) { + advancedCapabilities |= WIFI_FEATURE_WPA3_SAE; + } + + if ((capabilities & ISupplicantStaNetwork.KeyMgmtMask.SUITE_B_192) != 0) { + advancedCapabilities |= WIFI_FEATURE_WPA3_SUITE_B; + } + + if ((capabilities & ISupplicantStaNetwork.KeyMgmtMask.OWE) != 0) { + advancedCapabilities |= WIFI_FEATURE_OWE; + } + + logi(methodStr + ": Capability flags = " + capabilities); + + return advancedCapabilities; + } + } } diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java index 0efbf71c1..a7c231afb 100644 --- a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java +++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java @@ -16,10 +16,10 @@ package com.android.server.wifi; import android.content.Context; -import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback; import android.hardware.wifi.supplicant.V1_0.SupplicantStatus; import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; +import android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.os.HidlSupport.Mutable; @@ -27,6 +27,7 @@ import android.os.RemoteException; import android.text.TextUtils; import android.util.Log; import android.util.MutableBoolean; +import android.util.MutableInt; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -107,7 +108,10 @@ public class SupplicantStaNetworkHal { private int mAuthAlgMask; private int mGroupCipherMask; private int mPairwiseCipherMask; + private int mGroupMgmtCipherMask; private String mPskPassphrase; + private String mSaePassword; + private String mSaePasswordId; private byte[] mPsk; private ArrayList mWepKey; private int mWepTxKeyIdx; @@ -129,7 +133,7 @@ public class SupplicantStaNetworkHal { private String mEapDomainSuffixMatch; SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName, - Context context, WifiMonitor monitor) { + Context context, WifiMonitor monitor) { mISupplicantStaNetwork = iSupplicantStaNetwork; mIfaceName = ifaceName; mWifiMonitor = monitor; @@ -157,7 +161,7 @@ public class SupplicantStaNetworkHal { * @throws IllegalArgumentException on malformed configuration params. */ public boolean loadWifiConfiguration(WifiConfiguration config, - Map networkExtras) { + Map networkExtras) { synchronized (mLock) { if (config == null) return false; /** SSID */ @@ -209,7 +213,8 @@ public class SupplicantStaNetworkHal { config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase); } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) { config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk); - } + } /* Do not read SAE password */ + /** allowedKeyManagement */ if (getKeyMgmt()) { BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask); @@ -235,6 +240,12 @@ public class SupplicantStaNetworkHal { config.allowedPairwiseCiphers = supplicantToWifiConfigurationPairwiseCipherMask(mPairwiseCipherMask); } + /** allowedPairwiseCiphers */ + if (getGroupMgmtCipher()) { + config.allowedGroupMgmtCiphers = + supplicantToWifiConfigurationGroupMgmtCipherMask(mGroupMgmtCipherMask); + } + /** metadata: idstr */ if (getIdStr() && !TextUtils.isEmpty(mIdStr)) { Map metadata = parseNetworkExtra(mIdStr); @@ -273,14 +284,28 @@ public class SupplicantStaNetworkHal { } } /** Pre Shared Key */ - // This can either be quoted ASCII passphrase or hex string for raw psk. + // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk. + // For SAE, password must be a quoted ASCII string if (config.preSharedKey != null) { if (config.preSharedKey.startsWith("\"")) { - if (!setPskPassphrase(NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { - Log.e(TAG, "failed to set psk passphrase"); - return false; + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { + /* WPA3 case, field is SAE Password */ + if (!setSaePassword( + NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { + Log.e(TAG, "failed to set sae password"); + return false; + } + } else { + if (!setPskPassphrase( + NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { + Log.e(TAG, "failed to set psk passphrase"); + return false; + } } } else { + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { + return false; + } if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) { Log.e(TAG, "failed to set psk"); return false; @@ -314,6 +339,7 @@ public class SupplicantStaNetworkHal { Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID); return false; } + /** RequirePMF */ if (!setRequirePmf(config.requirePMF)) { Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePMF); @@ -327,6 +353,13 @@ public class SupplicantStaNetworkHal { Log.e(TAG, "failed to set Key Management"); return false; } + + // Check and set SuiteB configurations. + if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SUITE_B_192) + && !saveSuiteBConfig(config)) { + Log.e(TAG, "Failed to set Suite-B-192 configuration"); + return false; + } } /** Security Protocol */ if (config.allowedProtocols.cardinality() != 0 @@ -336,6 +369,7 @@ public class SupplicantStaNetworkHal { } /** Auth Algorithm */ if (config.allowedAuthAlgorithms.cardinality() != 0 + && isAuthAlgNeeded(config) && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask( config.allowedAuthAlgorithms))) { Log.e(TAG, "failed to set AuthAlgorithm"); @@ -343,8 +377,8 @@ public class SupplicantStaNetworkHal { } /** Group Cipher */ if (config.allowedGroupCiphers.cardinality() != 0 - && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( - config.allowedGroupCiphers))) { + && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( + config.allowedGroupCiphers)))) { Log.e(TAG, "failed to set Group Cipher"); return false; } @@ -391,10 +425,26 @@ public class SupplicantStaNetworkHal { } } + /** + * Check if Auth Alg is needed to be sent by wificonfiguration object + * Supplicant internally sets auth_alg and is not needed by framework + * to set the same + */ + private boolean isAuthAlgNeeded(WifiConfiguration config) { + BitSet keyMgmtMask = config.allowedKeyManagement; + if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SAE)) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "No need to set Auth Algorithm for SAE"); + } + return false; + } + return true; + } + /** * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object. * - * @param ssid SSID of the network. (Used for logging purposes only) + * @param ssid SSID of the network. (Used for logging purposes only) * @param eapConfig WifiEnterpriseConfig object to be populated. * @return true if succeeds, false otherwise. */ @@ -482,10 +532,54 @@ public class SupplicantStaNetworkHal { } } + /** + * Save network variables from the provided SuiteB configuration to wpa_supplicant. + * + * @param config WifiConfiguration object to be saved + * @return true if succeeds, false otherwise. + */ + private boolean saveSuiteBConfig(WifiConfiguration config) { + /** Group Cipher **/ + if (config.allowedGroupCiphers.cardinality() != 0 + && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( + config.allowedGroupCiphers))) { + Log.e(TAG, "failed to set Group Cipher"); + return false; + } + /** Pairwise Cipher*/ + if (config.allowedPairwiseCiphers.cardinality() != 0 + && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask( + config.allowedPairwiseCiphers))) { + Log.e(TAG, "failed to set PairwiseCipher"); + return false; + } + /** GroupMgmt Cipher */ + if (config.allowedGroupMgmtCiphers.cardinality() != 0 + && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask( + config.allowedGroupMgmtCiphers))) { + Log.e(TAG, "failed to set GroupMgmtCipher"); + return false; + } + + if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) { + if (!enableTlsSuiteBEapPhase1Param(true)) { + Log.e(TAG, "failed to set TLSSuiteB"); + return false; + } + } else if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) { + if (!enableSuiteBEapOpenSslCiphers()) { + Log.e(TAG, "failed to set OpensslCipher"); + return false; + } + } + + return true; + } + /** * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant. * - * @param ssid SSID of the network. (Used for logging purposes only) + * @param ssid SSID of the network. (Used for logging purposes only) * @param eapConfig WifiEnterpriseConfig object to be saved. * @return true if succeeds, false otherwise. */ @@ -589,19 +683,28 @@ public class SupplicantStaNetworkHal { Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam); return false; } + return true; } } + private android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork getV1_2StaNetwork() { + synchronized (mLock) { + return getSupplicantStaNetworkForV1_2Mockable(); + } + } + /** * Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int * TODO(b/32571829): Update mapping when fast transition keys are added + * * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant - * HIDL hal + * HIDL hal */ private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) { int mask = 0; - for (int bit = keyMgmt.nextSetBit(0); bit != -1; bit = keyMgmt.nextSetBit(bit + 1)) { + for (int bit = keyMgmt.nextSetBit(0); bit != -1; + bit = keyMgmt.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.KeyMgmt.NONE: mask |= ISupplicantStaNetwork.KeyMgmtMask.NONE; @@ -624,6 +727,15 @@ public class SupplicantStaNetworkHal { case WifiConfiguration.KeyMgmt.FT_EAP: mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_EAP; break; + case WifiConfiguration.KeyMgmt.OWE: + mask |= ISupplicantStaNetwork.KeyMgmtMask.OWE; + break; + case WifiConfiguration.KeyMgmt.SAE: + mask |= ISupplicantStaNetwork.KeyMgmtMask.SAE; + break; + case WifiConfiguration.KeyMgmt.SUITE_B_192: + mask |= ISupplicantStaNetwork.KeyMgmtMask.SUITE_B_192; + break; case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen default: throw new IllegalArgumentException( @@ -635,7 +747,8 @@ public class SupplicantStaNetworkHal { private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) { int mask = 0; - for (int bit = protoMask.nextSetBit(0); bit != -1; bit = protoMask.nextSetBit(bit + 1)) { + for (int bit = protoMask.nextSetBit(0); bit != -1; + bit = protoMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.Protocol.WPA: mask |= ISupplicantStaNetwork.ProtoMask.WPA; @@ -652,7 +765,7 @@ public class SupplicantStaNetworkHal { } } return mask; - }; + } private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) { int mask = 0; @@ -674,7 +787,7 @@ public class SupplicantStaNetworkHal { } } return mask; - }; + } private static int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) { int mask = 0; @@ -696,13 +809,41 @@ public class SupplicantStaNetworkHal { case WifiConfiguration.GroupCipher.GTK_NOT_USED: mask |= ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED; break; + case WifiConfiguration.GroupCipher.GCMP_256: + mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + .GroupCipherMask.GCMP_256; + break; default: throw new IllegalArgumentException( "Invalid GroupCipherMask bit in wificonfig: " + bit); } } return mask; - }; + } + + private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet + groupMgmtCipherMask) { + int mask = 0; + + for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit = + groupMgmtCipherMask.nextSetBit(bit + 1)) { + switch (bit) { + case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256: + mask |= ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_CMAC_256; + break; + case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128: + mask |= ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_GMAC_128; + break; + case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256: + mask |= ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_GMAC_256; + break; + default: + throw new IllegalArgumentException( + "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit); + } + } + return mask; + } private static int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) { int mask = 0; @@ -718,13 +859,16 @@ public class SupplicantStaNetworkHal { case WifiConfiguration.PairwiseCipher.CCMP: mask |= ISupplicantStaNetwork.PairwiseCipherMask.CCMP; break; + case WifiConfiguration.PairwiseCipher.GCMP_256: + mask |= ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256; + break; default: throw new IllegalArgumentException( "Invalid pairwiseCipherMask bit in wificonfig: " + bit); } } return mask; - }; + } private static int supplicantToWifiConfigurationEapMethod(int value) { switch (value) { @@ -749,7 +893,7 @@ public class SupplicantStaNetworkHal { Log.e(TAG, "invalid eap method value from supplicant: " + value); return -1; } - }; + } private static int supplicantToWifiConfigurationEapPhase2Method(int value) { switch (value) { @@ -773,11 +917,11 @@ public class SupplicantStaNetworkHal { Log.e(TAG, "invalid eap phase2 method value from supplicant: " + value); return -1; } - }; + } private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask, - int supplicantValue, BitSet bitset, - int bitSetPosition) { + int supplicantValue, BitSet bitset, + int bitSetPosition) { bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue); int modifiedSupplicantMask = supplicantMask & ~supplicantValue; return modifiedSupplicantMask; @@ -806,6 +950,16 @@ public class SupplicantStaNetworkHal { mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.FT_EAP, bitset, WifiConfiguration.KeyMgmt.FT_EAP); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.KeyMgmtMask.SAE, bitset, + WifiConfiguration.KeyMgmt.SAE); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.KeyMgmtMask.OWE, bitset, + WifiConfiguration.KeyMgmt.OWE); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.KeyMgmtMask.SUITE_B_192, bitset, + WifiConfiguration.KeyMgmt.SUITE_B_192); + if (mask != 0) { throw new IllegalArgumentException( "invalid key mgmt mask from supplicant: " + mask); @@ -829,7 +983,7 @@ public class SupplicantStaNetworkHal { "invalid proto mask from supplicant: " + mask); } return bitset; - }; + } private static BitSet supplicantToWifiConfigurationAuthAlgMask(int mask) { BitSet bitset = new BitSet(); @@ -847,7 +1001,7 @@ public class SupplicantStaNetworkHal { "invalid auth alg mask from supplicant: " + mask); } return bitset; - }; + } private static BitSet supplicantToWifiConfigurationGroupCipherMask(int mask) { BitSet bitset = new BitSet(); @@ -863,6 +1017,9 @@ public class SupplicantStaNetworkHal { mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset, WifiConfiguration.GroupCipher.CCMP); + mask = supplicantMaskValueToWifiConfigurationBitSet(mask, + ISupplicantStaNetwork.GroupCipherMask.GCMP_256, bitset, + WifiConfiguration.GroupCipher.GCMP_256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset, WifiConfiguration.GroupCipher.GTK_NOT_USED); @@ -871,7 +1028,25 @@ public class SupplicantStaNetworkHal { "invalid group cipher mask from supplicant: " + mask); } return bitset; - }; + } + + private static BitSet supplicantToWifiConfigurationGroupMgmtCipherMask(int mask) { + BitSet bitset = new BitSet(); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_GMAC_128, bitset, + WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_GMAC_256, bitset, + WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); + mask = supplicantMaskValueToWifiConfigurationBitSet( + mask, ISupplicantStaNetwork.GroupMgmtCipherMask.BIP_CMAC_256, bitset, + WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256); + if (mask != 0) { + throw new IllegalArgumentException( + "invalid group mgmt cipher mask from supplicant: " + mask); + } + return bitset; + } private static BitSet supplicantToWifiConfigurationPairwiseCipherMask(int mask) { BitSet bitset = new BitSet(); @@ -884,12 +1059,15 @@ public class SupplicantStaNetworkHal { mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.PairwiseCipherMask.CCMP, bitset, WifiConfiguration.PairwiseCipher.CCMP); + mask = supplicantMaskValueToWifiConfigurationBitSet(mask, + ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256, bitset, + WifiConfiguration.PairwiseCipher.GCMP_256); if (mask != 0) { throw new IllegalArgumentException( "invalid pairwise cipher mask from supplicant: " + mask); } return bitset; - }; + } private static int wifiConfigurationToSupplicantEapMethod(int value) { switch (value) { @@ -914,7 +1092,7 @@ public class SupplicantStaNetworkHal { Log.e(TAG, "invalid eap method value from WifiConfiguration: " + value); return -1; } - }; + } private static int wifiConfigurationToSupplicantEapPhase2Method(int value) { switch (value) { @@ -938,7 +1116,7 @@ public class SupplicantStaNetworkHal { Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value); return -1; } - }; + } /** See ISupplicantNetwork.hal for documentation */ private boolean getId() { @@ -969,7 +1147,7 @@ public class SupplicantStaNetworkHal { final String methodStr = "registerCallback"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.registerCallback(callback); + SupplicantStatus status = mISupplicantStaNetwork.registerCallback(callback); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -984,7 +1162,7 @@ public class SupplicantStaNetworkHal { final String methodStr = "setSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid); + SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1016,7 +1194,7 @@ public class SupplicantStaNetworkHal { final String methodStr = "setBssid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setBssid(bssid); + SupplicantStatus status = mISupplicantStaNetwork.setBssid(bssid); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1024,13 +1202,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setScanSsid(boolean enable) { synchronized (mLock) { final String methodStr = "setScanSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setScanSsid(enable); + SupplicantStatus status = mISupplicantStaNetwork.setScanSsid(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1038,13 +1217,25 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setKeyMgmt(int keyMgmtMask) { synchronized (mLock) { final String methodStr = "setKeyMgmt"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask); + SupplicantStatus status; + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for new key management types; SAE, OWE + * Requires HAL v1.2 or higher */ + status = iSupplicantStaNetworkV12.setKeyMgmt_1_2(keyMgmtMask); + } else { + status = mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask); + } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1052,13 +1243,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setProto(int protoMask) { synchronized (mLock) { final String methodStr = "setProto"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setProto(protoMask); + SupplicantStatus status = mISupplicantStaNetwork.setProto(protoMask); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1066,13 +1258,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setAuthAlg(int authAlgMask) { synchronized (mLock) { final String methodStr = "setAuthAlg"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setAuthAlg(authAlgMask); + SupplicantStatus status = mISupplicantStaNetwork.setAuthAlg(authAlgMask); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1080,13 +1273,26 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setGroupCipher(int groupCipherMask) { synchronized (mLock) { final String methodStr = "setGroupCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setGroupCipher(groupCipherMask); + SupplicantStatus status; + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for new key group cipher types for SuiteB + * Requires HAL v1.2 or higher */ + status = iSupplicantStaNetworkV12.setGroupCipher_1_2(groupCipherMask); + } else { + status = mISupplicantStaNetwork.setGroupCipher( + groupCipherMask); + } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1094,14 +1300,80 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean enableTlsSuiteBEapPhase1Param(boolean enable) { + synchronized (mLock) { + final String methodStr = "setEapPhase1Params"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for for SuiteB + * Requires HAL v1.2 or higher */ + SupplicantStatus status = iSupplicantStaNetworkV12 + .enableTlsSuiteBEapPhase1Param(enable); + return checkStatusAndLogFailure(status, methodStr); + } else { + Log.e(TAG, "Supplicant HAL version does not support " + methodStr); + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean enableSuiteBEapOpenSslCiphers() { + synchronized (mLock) { + final String methodStr = "setEapOpenSslCiphers"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for for SuiteB + * Requires HAL v1.2 or higher */ + SupplicantStatus status = iSupplicantStaNetworkV12 + .enableSuiteBEapOpenSslCiphers(); + return checkStatusAndLogFailure(status, methodStr); + } else { + Log.e(TAG, "Supplicant HAL version does not support " + methodStr); + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPairwiseCipher(int pairwiseCipherMask) { synchronized (mLock) { final String methodStr = "setPairwiseCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = - mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask); + SupplicantStatus status; + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for new key pairwise cipher types for SuiteB + * Requires HAL v1.2 or higher */ + status = iSupplicantStaNetworkV12.setPairwiseCipher_1_2(pairwiseCipherMask); + } else { + status = + mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask); + } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1109,13 +1381,41 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean setGroupMgmtCipher(int groupMgmtCipherMask) { + synchronized (mLock) { + final String methodStr = "setGroupMgmtCipher"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for new key pairwise cipher types for SuiteB + * Requires HAL v1.2 or higher */ + SupplicantStatus status = iSupplicantStaNetworkV12 + .setGroupMgmtCipher(groupMgmtCipherMask); + return checkStatusAndLogFailure(status, methodStr); + } else { + return false; + } + + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPskPassphrase(String psk) { synchronized (mLock) { final String methodStr = "setPskPassphrase"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setPskPassphrase(psk); + SupplicantStatus status = mISupplicantStaNetwork.setPskPassphrase(psk); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1123,13 +1423,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPsk(byte[] psk) { synchronized (mLock) { final String methodStr = "setPsk"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setPsk(psk); + SupplicantStatus status = mISupplicantStaNetwork.setPsk(psk); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1137,13 +1438,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setWepKey(int keyIdx, java.util.ArrayList wepKey) { synchronized (mLock) { final String methodStr = "setWepKey"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setWepKey(keyIdx, wepKey); + SupplicantStatus status = mISupplicantStaNetwork.setWepKey(keyIdx, wepKey); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1151,13 +1453,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setWepTxKeyIdx(int keyIdx) { synchronized (mLock) { final String methodStr = "setWepTxKeyIdx"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx); + SupplicantStatus status = mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1165,13 +1468,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setRequirePmf(boolean enable) { synchronized (mLock) { final String methodStr = "setRequirePmf"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable); + SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1179,13 +1483,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setUpdateIdentifier(int identifier) { synchronized (mLock) { final String methodStr = "setUpdateIdentifier"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setUpdateIdentifier(identifier); + SupplicantStatus status = mISupplicantStaNetwork.setUpdateIdentifier(identifier); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1193,13 +1498,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapMethod(int method) { synchronized (mLock) { final String methodStr = "setEapMethod"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapMethod(method); + SupplicantStatus status = mISupplicantStaNetwork.setEapMethod(method); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1207,13 +1513,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPhase2Method(int method) { synchronized (mLock) { final String methodStr = "setEapPhase2Method"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapPhase2Method(method); + SupplicantStatus status = mISupplicantStaNetwork.setEapPhase2Method(method); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1221,13 +1528,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapIdentity(java.util.ArrayList identity) { synchronized (mLock) { final String methodStr = "setEapIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapIdentity(identity); + SupplicantStatus status = mISupplicantStaNetwork.setEapIdentity(identity); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1235,13 +1543,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapAnonymousIdentity(java.util.ArrayList identity) { synchronized (mLock) { final String methodStr = "setEapAnonymousIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapAnonymousIdentity(identity); + SupplicantStatus status = mISupplicantStaNetwork.setEapAnonymousIdentity(identity); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1249,13 +1558,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPassword(java.util.ArrayList password) { synchronized (mLock) { final String methodStr = "setEapPassword"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapPassword(password); + SupplicantStatus status = mISupplicantStaNetwork.setEapPassword(password); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1263,13 +1573,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapCACert(String path) { synchronized (mLock) { final String methodStr = "setEapCACert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapCACert(path); + SupplicantStatus status = mISupplicantStaNetwork.setEapCACert(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1277,13 +1588,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapCAPath(String path) { synchronized (mLock) { final String methodStr = "setEapCAPath"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapCAPath(path); + SupplicantStatus status = mISupplicantStaNetwork.setEapCAPath(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1291,13 +1603,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapClientCert(String path) { synchronized (mLock) { final String methodStr = "setEapClientCert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapClientCert(path); + SupplicantStatus status = mISupplicantStaNetwork.setEapClientCert(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1305,13 +1618,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPrivateKeyId(String id) { synchronized (mLock) { final String methodStr = "setEapPrivateKeyId"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapPrivateKeyId(id); + SupplicantStatus status = mISupplicantStaNetwork.setEapPrivateKeyId(id); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1319,13 +1633,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapSubjectMatch(String match) { synchronized (mLock) { final String methodStr = "setEapSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapSubjectMatch(match); + SupplicantStatus status = mISupplicantStaNetwork.setEapSubjectMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1333,13 +1648,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapAltSubjectMatch(String match) { synchronized (mLock) { final String methodStr = "setEapAltSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapAltSubjectMatch(match); + SupplicantStatus status = mISupplicantStaNetwork.setEapAltSubjectMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1347,13 +1663,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapEngine(boolean enable) { synchronized (mLock) { final String methodStr = "setEapEngine"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapEngine(enable); + SupplicantStatus status = mISupplicantStaNetwork.setEapEngine(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1361,13 +1678,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapEngineID(String id) { synchronized (mLock) { final String methodStr = "setEapEngineID"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapEngineID(id); + SupplicantStatus status = mISupplicantStaNetwork.setEapEngineID(id); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1375,13 +1693,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapDomainSuffixMatch(String match) { synchronized (mLock) { final String methodStr = "setEapDomainSuffixMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setEapDomainSuffixMatch(match); + SupplicantStatus status = mISupplicantStaNetwork.setEapDomainSuffixMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1389,13 +1708,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapProactiveKeyCaching(boolean enable) { synchronized (mLock) { final String methodStr = "setEapProactiveKeyCaching"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setProactiveKeyCaching(enable); + SupplicantStatus status = mISupplicantStaNetwork.setProactiveKeyCaching(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1403,13 +1723,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean setIdStr(String idString) { synchronized (mLock) { final String methodStr = "setIdStr"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.setIdStr(idString); + SupplicantStatus status = mISupplicantStaNetwork.setIdStr(idString); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -1417,6 +1738,56 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean setSaePassword(String saePassword) { + synchronized (mLock) { + final String methodStr = "setSaePassword"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for SAE Requires HAL v1.2 or higher */ + SupplicantStatus status = iSupplicantStaNetworkV12.setSaePassword(saePassword); + return checkStatusAndLogFailure(status, methodStr); + } else { + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean setSaePasswordId(String saePasswordId) { + synchronized (mLock) { + final String methodStr = "setSaePasswordId"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for SAE Requires HAL v1.2 or higher */ + SupplicantStatus status = iSupplicantStaNetworkV12 + .setSaePasswordId(saePasswordId); + return checkStatusAndLogFailure(status, methodStr); + } else { + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getSsid() { synchronized (mLock) { @@ -1440,6 +1811,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getBssid() { synchronized (mLock) { @@ -1463,6 +1835,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getScanSsid() { synchronized (mLock) { @@ -1486,6 +1859,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getKeyMgmt() { synchronized (mLock) { @@ -1509,6 +1883,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getProto() { synchronized (mLock) { @@ -1531,6 +1906,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getAuthAlg() { synchronized (mLock) { @@ -1554,6 +1930,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getGroupCipher() { synchronized (mLock) { @@ -1577,6 +1954,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPairwiseCipher() { synchronized (mLock) { @@ -1600,6 +1978,38 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean getGroupMgmtCipher() { + synchronized (mLock) { + final String methodStr = "getGroupMgmtCipher"; + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + MutableBoolean statusOk = new MutableBoolean(false); + mISupplicantStaNetwork.getGroupMgmtCipher((SupplicantStatus status, + int groupMgmtCipherMaskValue) -> { + statusOk.value = status.code == SupplicantStatusCode.SUCCESS; + if (statusOk.value) { + this.mGroupMgmtCipherMask = groupMgmtCipherMaskValue; + } + checkStatusAndLogFailure(status, methodStr); + }); + return statusOk.value; + } else { + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPskPassphrase() { synchronized (mLock) { @@ -1623,6 +2033,38 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + private boolean getSaePassword() { + synchronized (mLock) { + final String methodStr = "getSaePassword"; + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; + try { + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + MutableBoolean statusOk = new MutableBoolean(false); + iSupplicantStaNetworkV12.getSaePassword((SupplicantStatus status, + String saePassword) -> { + statusOk.value = status.code == SupplicantStatusCode.SUCCESS; + if (statusOk.value) { + this.mSaePassword = saePassword; + } + checkStatusAndLogFailure(status, methodStr); + }); + return statusOk.value; + } else { + return false; + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + return false; + } + } + } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPsk() { synchronized (mLock) { @@ -1645,6 +2087,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getWepKey(int keyIdx) { synchronized (mLock) { @@ -1668,6 +2111,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getWepTxKeyIdx() { synchronized (mLock) { @@ -1691,6 +2135,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getRequirePmf() { synchronized (mLock) { @@ -1714,6 +2159,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapMethod() { synchronized (mLock) { @@ -1737,6 +2183,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapPhase2Method() { synchronized (mLock) { @@ -1760,6 +2207,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapIdentity() { synchronized (mLock) { @@ -1783,6 +2231,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapAnonymousIdentity() { synchronized (mLock) { @@ -1845,6 +2294,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapCACert() { synchronized (mLock) { @@ -1867,6 +2317,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapCAPath() { synchronized (mLock) { @@ -1889,6 +2340,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapClientCert() { synchronized (mLock) { @@ -1912,6 +2364,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapPrivateKeyId() { synchronized (mLock) { @@ -1935,6 +2388,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapSubjectMatch() { synchronized (mLock) { @@ -1958,6 +2412,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapAltSubjectMatch() { synchronized (mLock) { @@ -1981,6 +2436,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapEngine() { synchronized (mLock) { @@ -2004,6 +2460,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapEngineID() { synchronized (mLock) { @@ -2026,6 +2483,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapDomainSuffixMatch() { synchronized (mLock) { @@ -2049,6 +2507,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean getIdStr() { synchronized (mLock) { @@ -2071,13 +2530,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean enable(boolean noConnect) { synchronized (mLock) { final String methodStr = "enable"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.enable(noConnect); + SupplicantStatus status = mISupplicantStaNetwork.enable(noConnect); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -2085,13 +2545,14 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean disable() { synchronized (mLock) { final String methodStr = "disable"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.disable(); + SupplicantStatus status = mISupplicantStaNetwork.disable(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -2110,7 +2571,7 @@ public class SupplicantStaNetworkHal { final String methodStr = "select"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { - SupplicantStatus status = mISupplicantStaNetwork.select(); + SupplicantStatus status = mISupplicantStaNetwork.select(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); @@ -2181,6 +2642,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ public boolean sendNetworkEapSimGsmAuthFailure() { synchronized (mLock) { @@ -2195,6 +2657,7 @@ public class SupplicantStaNetworkHal { } } } + /** * Send UMTS auth response. * @@ -2255,6 +2718,7 @@ public class SupplicantStaNetworkHal { } } } + /** * Send UMTS auts response. * @@ -2281,6 +2745,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) { synchronized (mLock) { @@ -2296,6 +2761,7 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ public boolean sendNetworkEapSimUmtsAuthFailure() { synchronized (mLock) { @@ -2324,15 +2790,28 @@ public class SupplicantStaNetworkHal { mISupplicantStaNetwork); } + /** + * Method to mock out the V1_2 ISupplicantStaNetwork retrieval in unit tests. + * + * @return 1.2 ISupplicantStaNetwork object if the device is running the 1.2 supplicant hal + * service, null otherwise. + */ + protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + getSupplicantStaNetworkForV1_2Mockable() { + if (mISupplicantStaNetwork == null) return null; + return android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.castFrom( + mISupplicantStaNetwork); + } + /** * Send eap identity response. * - * @param identityStr identity used for EAP-Identity + * @param identityStr identity used for EAP-Identity * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM * @return true if succeeds, false otherwise. */ public boolean sendNetworkEapIdentityResponse(String identityStr, - String encryptedIdentityStr) { + String encryptedIdentityStr) { synchronized (mLock) { try { ArrayList unencryptedIdentity = @@ -2348,9 +2827,10 @@ public class SupplicantStaNetworkHal { } } } + /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapIdentityResponse(ArrayList unencryptedIdentity, - ArrayList encryptedIdentity) { + ArrayList encryptedIdentity) { synchronized (mLock) { final String methodStr = "sendNetworkEapIdentityResponse"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; @@ -2594,4 +3074,40 @@ public class SupplicantStaNetworkHal { } } } + + /** See ISupplicantStaNetwork.hal for documentation */ + public int getKeyMgmtCapabilities() { + synchronized (mLock) { + final String methodStr = "getKeyMgmtCapabilities"; + if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return 0; + try { + MutableBoolean status = new MutableBoolean(false); + MutableInt keyMgmtMask = new MutableInt(0); + android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork + iSupplicantStaNetworkV12; + + iSupplicantStaNetworkV12 = getV1_2StaNetwork(); + if (iSupplicantStaNetworkV12 != null) { + /* Support for new key management types; SAE, OWE + * Requires HAL v1.2 or higher */ + iSupplicantStaNetworkV12.getKeyMgmtCapabilities( + (SupplicantStatus statusInternal, int keyMgmtMaskIntenral) -> { + status.value = statusInternal.code == SupplicantStatusCode.SUCCESS; + if (status.value) { + keyMgmtMask.value = keyMgmtMaskIntenral; + } + checkStatusAndLogFailure(statusInternal, methodStr); + }); + + return keyMgmtMask.value; + } else { + Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); + } + } catch (RemoteException e) { + handleRemoteException(e, methodStr); + } + } + + return 0; + } } diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 98fb945af..8c40c6a13 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -822,6 +822,8 @@ public class WifiConfigManager { internalConfig.BSSID = externalConfig.BSSID.toLowerCase(); } internalConfig.hiddenSSID = externalConfig.hiddenSSID; + internalConfig.requirePMF = externalConfig.requirePMF; + if (externalConfig.preSharedKey != null && !externalConfig.preSharedKey.equals(PASSWORD_MASK)) { internalConfig.preSharedKey = externalConfig.preSharedKey; @@ -877,6 +879,16 @@ public class WifiConfigManager { internalConfig.allowedGroupCiphers = (BitSet) externalConfig.allowedGroupCiphers.clone(); } + if (externalConfig.allowedGroupMgmtCiphers != null + && !externalConfig.allowedGroupMgmtCiphers.isEmpty()) { + internalConfig.allowedGroupMgmtCiphers = + (BitSet) externalConfig.allowedGroupMgmtCiphers.clone(); + } + if (externalConfig.allowedSuiteBCiphers != null + && !externalConfig.allowedSuiteBCiphers.isEmpty()) { + internalConfig.allowedSuiteBCiphers = + (BitSet) externalConfig.allowedSuiteBCiphers.clone(); + } // Copy over the |IpConfiguration| parameters if set. if (externalConfig.getIpConfiguration() != null) { diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java index 9bf6e327d..0ebac1427 100644 --- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java +++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java @@ -122,6 +122,20 @@ public class WifiConfigurationUtil { return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK); } + /** + * Helper method to check if the provided |config| corresponds to an SAE network or not. + */ + public static boolean isConfigForSaeNetwork(WifiConfiguration config) { + return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE); + } + + /** + * Helper method to check if the provided |config| corresponds to an OWE network or not. + */ + public static boolean isConfigForOweNetwork(WifiConfiguration config) { + return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE); + } + /** * Helper method to check if the provided |config| corresponds to a EAP network or not. */ @@ -130,6 +144,13 @@ public class WifiConfigurationUtil { || config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); } + /** + * Helper method to check if the provided |config| corresponds to a EAP Suite-B network or not. + */ + public static boolean isConfigForEapSuiteBNetwork(WifiConfiguration config) { + return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192); + } + /** * Helper method to check if the provided |config| corresponds to a WEP network or not. */ @@ -139,11 +160,13 @@ public class WifiConfigurationUtil { } /** - * Helper method to check if the provided |config| corresponds to an open network or not. + * Helper method to check if the provided |config| corresponds to an open or enhanced + * open network, or not. */ public static boolean isConfigForOpenNetwork(WifiConfiguration config) { - return !(isConfigForWepNetwork(config) || isConfigForPskNetwork(config) - || isConfigForEapNetwork(config)); + return (!(isConfigForWepNetwork(config) || isConfigForPskNetwork(config) + || isConfigForEapNetwork(config) || isConfigForSaeNetwork(config) + || isConfigForEapSuiteBNetwork(config))); } /** @@ -262,6 +285,14 @@ public class WifiConfigurationUtil { newConfig.allowedGroupCiphers)) { return true; } + if (!Objects.equals(existingConfig.allowedGroupMgmtCiphers, + newConfig.allowedGroupMgmtCiphers)) { + return true; + } + if (!Objects.equals(existingConfig.allowedSuiteBCiphers, + newConfig.allowedSuiteBCiphers)) { + return true; + } if (!Objects.equals(existingConfig.preSharedKey, newConfig.preSharedKey)) { return true; } @@ -274,6 +305,9 @@ public class WifiConfigurationUtil { if (existingConfig.hiddenSSID != newConfig.hiddenSSID) { return true; } + if (existingConfig.requirePMF != newConfig.requirePMF) { + return true; + } if (hasEnterpriseConfigChanged(existingConfig.enterpriseConfig, newConfig.enterpriseConfig)) { return true; diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 5f1e09b75..b23ec7221 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -872,10 +872,12 @@ public class WifiMetrics { if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) { mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; - } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) { + } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) + || ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; - } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { + } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult) + || ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; } @@ -1367,10 +1369,12 @@ public class WifiMetrics { } } if (scanResult != null && scanResult.capabilities != null) { - if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { + if (ScanResultUtil.isScanResultForEapNetwork(scanResult) + || ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { enterpriseNetworks++; } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) - || ScanResultUtil.isScanResultForWepNetwork(scanResult)) { + || ScanResultUtil.isScanResultForWepNetwork(scanResult) + || ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { personalNetworks++; } else { openNetworks++; diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index f148e01b6..074cfd327 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -2297,7 +2297,8 @@ public class WifiNative { * @return bitmask defined by WifiManager.WIFI_FEATURE_* */ public int getSupportedFeatureSet(@NonNull String ifaceName) { - return mWifiVendorHal.getSupportedFeatureSet(ifaceName); + return mSupplicantStaIfaceHal.getAdvancedKeyMgmtCapabilities(ifaceName) + | mWifiVendorHal.getSupportedFeatureSet(ifaceName); } /** diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java index 2128a410d..26ede7047 100644 --- a/service/java/com/android/server/wifi/util/InformationElementUtil.java +++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java @@ -400,6 +400,7 @@ public class InformationElementUtil { private static final int WPA_VENDOR_OUI_TYPE_ONE = 0x01f25000; private static final int WPS_VENDOR_OUI_TYPE = 0x04f25000; private static final short WPA_VENDOR_OUI_VERSION = 0x0001; + private static final int OWE_VENDOR_OUI_TYPE = 0x1c9a6f50; private static final short RSNE_VERSION = 0x0001; private static final int WPA_AKM_EAP = 0x01f25000; @@ -411,6 +412,9 @@ public class InformationElementUtil { private static final int WPA2_AKM_FT_PSK = 0x04ac0f00; private static final int WPA2_AKM_EAP_SHA256 = 0x05ac0f00; private static final int WPA2_AKM_PSK_SHA256 = 0x06ac0f00; + private static final int WPA2_AKM_SAE = 0x08ac0f00; + private static final int WPA2_AKM_OWE = 0x12ac0f00; + private static final int WPA2_AKM_EAP_SUITE_B_192 = 0x0cac0f00; private static final int WPA_CIPHER_NONE = 0x00f25000; private static final int WPA_CIPHER_TKIP = 0x02f25000; @@ -420,6 +424,7 @@ public class InformationElementUtil { private static final int RSN_CIPHER_TKIP = 0x02ac0f00; private static final int RSN_CIPHER_CCMP = 0x04ac0f00; private static final int RSN_CIPHER_NO_GROUP_ADDRESSED = 0x07ac0f00; + private static final int RSN_CIPHER_GCMP_256 = 0x09ac0f00; public ArrayList protocol; public ArrayList> keyManagement; @@ -456,7 +461,7 @@ public class InformationElementUtil { } // found the RSNE IE, hence start building the capability string - protocol.add(ScanResult.PROTOCOL_WPA2); + protocol.add(ScanResult.PROTOCOL_RSN); // group data cipher suite groupCipher.add(parseRsnCipher(buf.getInt())); @@ -496,6 +501,15 @@ public class InformationElementUtil { case WPA2_AKM_PSK_SHA256: rsnKeyManagement.add(ScanResult.KEY_MGMT_PSK_SHA256); break; + case WPA2_AKM_SAE: + rsnKeyManagement.add(ScanResult.KEY_MGMT_SAE); + break; + case WPA2_AKM_OWE: + rsnKeyManagement.add(ScanResult.KEY_MGMT_OWE); + break; + case WPA2_AKM_EAP_SUITE_B_192: + rsnKeyManagement.add(ScanResult.KEY_MGMT_EAP_SUITE_B_192); + break; default: // do nothing break; @@ -534,6 +548,8 @@ public class InformationElementUtil { return ScanResult.CIPHER_TKIP; case RSN_CIPHER_CCMP: return ScanResult.CIPHER_CCMP; + case RSN_CIPHER_GCMP_256: + return ScanResult.CIPHER_GCMP_256; case RSN_CIPHER_NO_GROUP_ADDRESSED: return ScanResult.CIPHER_NO_GROUP_ADDRESSED; default: @@ -671,18 +687,50 @@ public class InformationElementUtil { // TODO(b/62134557): parse WPS IE to provide finer granularity information. isWPS = true; } + if (isOweElement(ie)) { + /* From RFC 8110: Once the client and AP have finished 802.11 association, + they then complete the Diffie-Hellman key exchange and create a Pairwise + Master Key (PMK) and its associated identifier, PMKID [IEEE802.11]. + Upon completion of 802.11 association, the AP initiates the 4-way + handshake to the client using the PMK generated above. The 4-way + handshake generates a Key-Encrypting Key (KEK), a Key-Confirmation + Key (KCK), and a Message Integrity Code (MIC) to use for protection + of the frames that define the 4-way handshake. + */ + + protocol.add(ScanResult.PROTOCOL_RSN); + groupCipher.add(ScanResult.CIPHER_CCMP); + ArrayList owePairwiseCipher = new ArrayList<>(); + owePairwiseCipher.add(ScanResult.CIPHER_CCMP); + pairwiseCipher.add(owePairwiseCipher); + ArrayList oweKeyManagement = new ArrayList<>(); + oweKeyManagement.add(ScanResult.KEY_MGMT_OWE); + keyManagement.add(oweKeyManagement); + } } } } + private static boolean isOweElement(InformationElement ie) { + ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN); + try { + // OWE OUI and type + return (buf.getInt() == OWE_VENDOR_OUI_TYPE); + } catch (BufferUnderflowException e) { + Log.e("IE_Capabilities", "Couldn't parse VSA IE, buffer underflow"); + return false; + } + } + + private String protocolToString(int protocol) { switch (protocol) { case ScanResult.PROTOCOL_NONE: return "None"; case ScanResult.PROTOCOL_WPA: return "WPA"; - case ScanResult.PROTOCOL_WPA2: - return "WPA2"; + case ScanResult.PROTOCOL_RSN: + return "RSN"; default: return "?"; } @@ -704,6 +752,12 @@ public class InformationElementUtil { return "EAP-SHA256"; case ScanResult.KEY_MGMT_PSK_SHA256: return "PSK-SHA256"; + case ScanResult.KEY_MGMT_OWE: + return "OWE"; + case ScanResult.KEY_MGMT_SAE: + return "SAE"; + case ScanResult.KEY_MGMT_EAP_SUITE_B_192: + return "EAP_SUITE_B_192"; default: return "?"; } @@ -715,6 +769,8 @@ public class InformationElementUtil { return "None"; case ScanResult.CIPHER_CCMP: return "CCMP"; + case ScanResult.CIPHER_GCMP_256: + return "GCMP-256"; case ScanResult.CIPHER_TKIP: return "TKIP"; default: diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java index cfe09d565..28ad1638f 100644 --- a/service/java/com/android/server/wifi/util/ScanResultUtil.java +++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java @@ -62,6 +62,14 @@ public class ScanResultUtil { return scanResult.capabilities.contains("EAP"); } + /** + * Helper method to check if the provided |scanResult| corresponds to a EAP network or not. + * This checks if the provided capabilities string contains EAP encryption type or not. + */ + public static boolean isScanResultForEapSuiteBNetwork(ScanResult scanResult) { + return scanResult.capabilities.contains("SUITE-B-192"); + } + /** * Helper method to check if the provided |scanResult| corresponds to a WEP network or not. * This checks if the provided capabilities string contains WEP encryption type or not. @@ -70,14 +78,31 @@ public class ScanResultUtil { return scanResult.capabilities.contains("WEP"); } + /** + * Helper method to check if the provided |scanResult| corresponds to OWE network. + * This checks if the provided capabilities string contains OWE or not. + */ + public static boolean isScanResultForOweNetwork(ScanResult scanResult) { + return scanResult.capabilities.contains("OWE"); + } + + /** + * Helper method to check if the provided |scanResult| corresponds to SAE network. + * This checks if the provided capabilities string contains SAE or not. + */ + public static boolean isScanResultForSaeNetwork(ScanResult scanResult) { + return scanResult.capabilities.contains("SAE"); + } + /** * Helper method to check if the provided |scanResult| corresponds to an open network or not. - * This checks if the provided capabilities string does not contain either of WEP, PSK or EAP - * encryption types or not. + * This checks if the provided capabilities string does not contain either of WEP, PSK, SAE + * or EAP encryption types or not. */ public static boolean isScanResultForOpenNetwork(ScanResult scanResult) { - return !(isScanResultForWepNetwork(scanResult) || isScanResultForPskNetwork(scanResult) - || isScanResultForEapNetwork(scanResult)); + return (!(isScanResultForWepNetwork(scanResult) || isScanResultForPskNetwork(scanResult) + || isScanResultForEapNetwork(scanResult) || isScanResultForSaeNetwork(scanResult) + || isScanResultForEapSuiteBNetwork(scanResult))); } /** @@ -106,8 +131,12 @@ public class ScanResultUtil { */ public static void setAllowedKeyManagementFromScanResult(ScanResult scanResult, WifiConfiguration config) { - if (isScanResultForPskNetwork(scanResult)) { + if (isScanResultForSaeNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); + } else if (isScanResultForPskNetwork(scanResult)) { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + } else if (isScanResultForEapSuiteBNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); } else if (isScanResultForEapNetwork(scanResult)) { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); @@ -115,6 +144,8 @@ public class ScanResultUtil { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); + } else if (isScanResultForOweNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); } else { config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java index 4e1d3b3a3..15d6c1b25 100644 --- a/service/java/com/android/server/wifi/util/XmlUtil.java +++ b/service/java/com/android/server/wifi/util/XmlUtil.java @@ -323,6 +323,8 @@ public class XmlUtil { public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos"; public static final String XML_TAG_ALLOWED_GROUP_CIPHERS = "AllowedGroupCiphers"; public static final String XML_TAG_ALLOWED_PAIRWISE_CIPHERS = "AllowedPairwiseCiphers"; + public static final String XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS = "AllowedGroupMgmtCiphers"; + public static final String XML_TAG_ALLOWED_SUITE_B_CIPHERS = "AllowedSuiteBCiphers"; public static final String XML_TAG_SHARED = "Shared"; public static final String XML_TAG_STATUS = "Status"; public static final String XML_TAG_FQDN = "FQDN"; @@ -406,6 +408,12 @@ public class XmlUtil { XmlUtil.writeNextValue( out, XML_TAG_ALLOWED_PAIRWISE_CIPHERS, configuration.allowedPairwiseCiphers.toByteArray()); + XmlUtil.writeNextValue( + out, XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS, + configuration.allowedGroupMgmtCiphers.toByteArray()); + XmlUtil.writeNextValue( + out, XML_TAG_ALLOWED_SUITE_B_CIPHERS, + configuration.allowedSuiteBCiphers.toByteArray()); XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared); } @@ -562,6 +570,16 @@ public class XmlUtil { configuration.allowedPairwiseCiphers = BitSet.valueOf(allowedPairwiseCiphers); break; + case XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS: + byte[] allowedGroupMgmtCiphers = (byte[]) value; + configuration.allowedGroupMgmtCiphers = + BitSet.valueOf(allowedGroupMgmtCiphers); + break; + case XML_TAG_ALLOWED_SUITE_B_CIPHERS: + byte[] allowedSuiteBCiphers = (byte[]) value; + configuration.allowedSuiteBCiphers = + BitSet.valueOf(allowedSuiteBCiphers); + break; case XML_TAG_SHARED: configuration.shared = (boolean) value; break; -- cgit v1.2.3