diff options
8 files changed, 334 insertions, 14 deletions
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig index 7710231bff..93f6d076c5 100644 --- a/flags/wifi_flags.aconfig +++ b/flags/wifi_flags.aconfig @@ -127,3 +127,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "rsn_overriding" + namespace: "wifi" + description: "Wi-Fi Alliance RSN Overriding feature" + bug: "348669010" + is_fixed_read_only: true +} diff --git a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java index 4a485c06ab..5a51ac6e5f 100644 --- a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java +++ b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java @@ -363,6 +363,33 @@ public class ScanResultUtilTest { } /** + * Test that a network configured in WPA3-Compatibility mode is detected as WPA3-transition mode + */ + @Test + public void testWPA3CompatibilityModeNetwork() { + final String ssid = "WPA3-Compatibility"; + String caps = "[WPA2-PSK-CCMP][RSN-PSK-CCMP][RSN-SAE-CCMP][MFPC][RSNO]"; + + ScanResult input = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid), + "ab:cd:01:ef:45:89") + .setHessid(1245) + .setCaps(caps) + .setRssi(-78) + .setFrequency(2450) + .setTsf(1025) + .setDistanceCm(22) + .setDistanceSdCm(33) + .setIs80211McRTTResponder(true) + .build(); + + input.informationElements = new InformationElement[] { + createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8)) + }; + + assertTrue(ScanResultUtil.isScanResultForPskSaeTransitionNetwork(input)); + } + + /** * Test that a PSK network is not detected as transition mode */ @Test diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml index cb76012876..454eb236fd 100644 --- a/service/ServiceWifiResources/res/values/config.xml +++ b/service/ServiceWifiResources/res/values/config.xml @@ -1363,4 +1363,11 @@ See also config_wifiDelayedSelectionCarrierIds. --> <integer translatable="false" name="config_wifiDelayedCarrierSelectionTimeMs">90000</integer> + + <!-- Boolean indicating whether the device supports Wi-Fi Alliance WPA3 Specification + version 3.3 Section 14 - RSN Overriding. + Enabling this config allows framework to parse the RSNO IE and RSNO2 IE. + Only enable this flag if Supplicant and driver/firmware supports RSN Overriding. otherwise + the connection may fail or downgrade to WPA2 --> + <bool translatable="false" name ="config_wifiRsnOverridingEnabled">false</bool> </resources> diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml index e2cd626f8f..247797c2b2 100644 --- a/service/ServiceWifiResources/res/values/overlayable.xml +++ b/service/ServiceWifiResources/res/values/overlayable.xml @@ -348,6 +348,7 @@ <item type="bool" name="config_wifiWepAllowedControlSupported" /> <item type="array" name="config_wifiDelayedSelectionCarrierIds" /> <item type="integer" name="config_wifiDelayedCarrierSelectionTimeMs" /> + <item type="bool" name="config_wifiRsnOverridingEnabled" /> <!-- Params from config.xml that can be overlayed --> diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 9ec97ee493..61ccf321b3 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -21,11 +21,12 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_NAN; -import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P; +import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA; import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES; import static com.android.server.wifi.p2p.WifiP2pNative.P2P_IFACE_NAME; import static com.android.server.wifi.p2p.WifiP2pNative.P2P_INTERFACE_PROPERTY; +import static com.android.wifi.flags.Flags.rsnOverriding; import android.annotation.IntDef; import android.annotation.NonNull; @@ -134,6 +135,7 @@ public class WifiNative { private NetdWrapper mNetdWrapper; private boolean mVerboseLoggingEnabled = false; private boolean mIsEnhancedOpenSupported = false; + @VisibleForTesting boolean mIsRsnOverridingSupported = false; private final List<CoexUnsafeChannel> mCachedCoexUnsafeChannels = new ArrayList<>(); private int mCachedCoexRestrictions; private CountryCodeChangeListenerInternal mCountryCodeChangeListener; @@ -1557,6 +1559,8 @@ public class WifiNative { iface.featureSet = getSupportedFeatureSetInternal(iface.name); updateSupportedBandForStaInternal(iface); + mIsRsnOverridingSupported = mContext.getResources().getBoolean( + R.bool.config_wifiRsnOverridingEnabled) && rsnOverriding(); mWifiVendorHal.enableStaChannelForPeerNetwork(mContext.getResources().getBoolean( R.bool.config_wifiEnableStaIndoorChannelForPeerNetwork), @@ -2090,6 +2094,7 @@ public class WifiNative { ies, result.getCapabilities(), mIsEnhancedOpenSupported, + mIsRsnOverridingSupported, result.getFrequencyMhz(), mUnknownAkmMap); String flags = capabilities.generateCapabilitiesString(); diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java index 57643b9c01..ea499578df 100644 --- a/service/java/com/android/server/wifi/util/InformationElementUtil.java +++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java @@ -1859,6 +1859,8 @@ public class InformationElementUtil { 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 int RSNE_OVERRIDE_VENDOR_OUI_TYPE = 0x299a6f50; + private static final int RSNE_OVERRIDE2_VENDOR_OUI_TYPE = 0x2A9a6f50; private static final short RSNE_VERSION = 0x0001; private static final int WPA_AKM_EAP = 0x01f25000; @@ -1910,10 +1912,25 @@ public class InformationElementUtil { public boolean isWPS; public boolean isManagementFrameProtectionRequired; public boolean isManagementFrameProtectionCapable; + private boolean mHasPmfRequiredBitSetToFalseOccurred; + public boolean isRSNEOverrideElementPresent; public Capabilities() { } + private static boolean isRsneOverrideElement(InformationElement ie) { + ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN); + try { + int vendorOuiType = buf.getInt(); + // Wi-Fi Alliance specific OUI and OUI type identifying RSNE Override element. + return (vendorOuiType == RSNE_OVERRIDE_VENDOR_OUI_TYPE + || vendorOuiType == RSNE_OVERRIDE2_VENDOR_OUI_TYPE); + } catch (BufferUnderflowException e) { + Log.e("IE_Capabilities", "Couldn't parse VSA IE, buffer underflow"); + return false; + } + } + // RSNE format (size unit: byte) // // | Element ID | Length | Version | Group Data Cipher Suite | @@ -1927,8 +1944,7 @@ public class InformationElementUtil { // // Note: InformationElement.bytes has 'Element ID' and 'Length' // stripped off already - private void parseRsnElement(InformationElement ie, SparseIntArray unknownAkmMap) { - ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN); + private void parseRsnElement(ByteBuffer buf, SparseIntArray unknownAkmMap) { try { // version @@ -2027,9 +2043,17 @@ public class InformationElementUtil { // see section 9.4.2.25 - RSNE - In IEEE Std 802.11-2016 if (buf.remaining() < 2) return; int rsnCaps = buf.getShort(); - isManagementFrameProtectionRequired = - 0 != (RSN_CAP_MANAGEMENT_FRAME_PROTECTION_REQUIRED & rsnCaps); - isManagementFrameProtectionCapable = + // This method gets called multiple times if the AP and STA supports RSN overriding. + // The PMF required bit should be set to false if one of the RSN fields PMF + // required bit is ever false. The PMF capable bit should be set to true if one of + // the RSN fields PMF capable bit is ever true. + if ((RSN_CAP_MANAGEMENT_FRAME_PROTECTION_REQUIRED & rsnCaps) == 0) { + mHasPmfRequiredBitSetToFalseOccurred = true; + isManagementFrameProtectionRequired = false; + } else if (!mHasPmfRequiredBitSetToFalseOccurred) { + isManagementFrameProtectionRequired = true; + } + isManagementFrameProtectionCapable |= 0 != (RSN_CAP_MANAGEMENT_FRAME_PROTECTION_CAPABLE & rsnCaps); if (buf.remaining() < 2) return; @@ -2218,6 +2242,8 @@ public class InformationElementUtil { * @param ies -- Information Element array * @param beaconCap -- 16-bit Beacon Capability Information field * @param isOweSupported -- Boolean flag to indicate if OWE is supported by the device + * @param isRsnOverridingSupported -- Boolean flag to indicate if RSN Overriding is + * supported by the device * @param freq -- Frequency on which frame/beacon was transmitted. Some parsing may be * affected such as DMG parameters in DMG (60GHz) beacon. * @param unknownAkmMap -- unknown AKM to known AKM mapping (Internally converted to @@ -2228,6 +2254,7 @@ public class InformationElementUtil { InformationElement[] ies, int beaconCap, boolean isOweSupported, + boolean isRsnOverridingSupported, int freq, SparseIntArray unknownAkmMap) { protocol = new ArrayList<>(); @@ -2265,10 +2292,22 @@ public class InformationElementUtil { } if (ie.id == InformationElement.EID_RSN) { - parseRsnElement(ie, unknownAkmMap); + parseRsnElement(ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN), + unknownAkmMap); } if (ie.id == InformationElement.EID_VSA) { + if (isRsnOverridingSupported && isRsneOverrideElement(ie)) { + ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN); + // RSN Override and RSN Override 2 vendor specific element begins + // with 3 bytes of Wi-Fi Alliance specific OUI and 1 byte of OUI type. + // The Payload field of the RSNE Override element and the RSNE Override 2 + // element uses the same format as the Information field of the RSNE. + // So skip the 4 byte OUI field and proceed to parse the RSN element. + buf.getInt(); + parseRsnElement(buf, unknownAkmMap); + isRSNEOverrideElementPresent = true; + } if (isWpaOneElement(ie)) { parseWpaOneElement(ie, unknownAkmMap); } @@ -2474,6 +2513,9 @@ public class InformationElementUtil { if (isManagementFrameProtectionCapable) { capabilities.append("[MFPC]"); } + if (isRSNEOverrideElementPresent) { + capabilities.append("[RSNO]"); + } return capabilities.toString(); } diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java index cff25254dd..1027f13124 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java @@ -43,6 +43,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.validateMockitoUsage; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; import android.net.MacAddress; import android.net.wifi.CoexUnsafeChannel; @@ -52,6 +53,7 @@ import android.net.wifi.WifiAvailableChannel; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiContext; import android.net.wifi.WifiManager; +import android.net.wifi.WifiMigration; import android.net.wifi.WifiScanner; import android.net.wifi.WifiScanner.ScanData; import android.net.wifi.WifiSsid; @@ -73,6 +75,7 @@ import com.android.server.wifi.hal.WifiChip; import com.android.server.wifi.proto.WifiStatsLog; import com.android.server.wifi.util.NativeUtil; import com.android.server.wifi.util.NetdWrapper; +import com.android.wifi.flags.Flags; import com.android.wifi.resources.R; import org.junit.After; @@ -344,8 +347,12 @@ public class WifiNativeTest extends WifiBaseTest { mSession = ExtendedMockito.mockitoSession() .strictness(Strictness.LENIENT) .mockStatic(WifiStatsLog.class) + .mockStatic(Flags.class, withSettings().lenient()) + .mockStatic(WifiMigration.class, withSettings().lenient()) .startMocking(); + when(Flags.rsnOverriding()).thenReturn(false); + mWifiNative = new WifiNative( mWifiVendorHal, mStaIfaceHal, mHostapdHal, mWificondControl, mWifiMonitor, mPropertyService, mWifiMetrics, @@ -1820,4 +1827,18 @@ public class WifiNativeTest extends WifiBaseTest { WifiManager.ROAMING_MODE_NORMAL)); verify(mWifiVendorHal).setRoamingMode(WIFI_IFACE_NAME, WifiManager.ROAMING_MODE_NORMAL); } + + @Test + public void testRsnOverridingFeatureFlag() throws Exception { + mResources.setBoolean(R.bool.config_wifiRsnOverridingEnabled, true); + when(Flags.rsnOverriding()).thenReturn(false); + mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE, + mConcreteClientModeManager); + assertFalse(mWifiNative.mIsRsnOverridingSupported); + mWifiNative.teardownAllInterfaces(); + when(Flags.rsnOverriding()).thenReturn(true); + mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE, + mConcreteClientModeManager); + assertTrue(mWifiNative.mIsRsnOverridingSupported); + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java index 0d5e495193..abc04e5f9d 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java @@ -466,11 +466,13 @@ public class InformationElementUtilTest extends WifiBaseTest { InformationElement[] ies, int beaconCap, boolean isOweSupported, + boolean isRsnOverridingSupported, String capsStr, SparseIntArray unknownAkmMap) { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap, isOweSupported, 2400, unknownAkmMap); + capabilities.from(ies, beaconCap, isOweSupported, isRsnOverridingSupported, 2400, + unknownAkmMap); String result = capabilities.generateCapabilitiesString(); assertEquals(capsStr, result); @@ -484,7 +486,8 @@ public class InformationElementUtilTest extends WifiBaseTest { SparseIntArray unknownAkmMap) { InformationElement[] ies = new InformationElement[] { ie }; verifyCapabilityStringFromIes( - new InformationElement[] {ie}, beaconCap, isOweSupported, capsStr, unknownAkmMap); + new InformationElement[] {ie}, beaconCap, isOweSupported, false, capsStr, + unknownAkmMap); } private void verifyCapabilityStringFromIeWithoutOweSupported( @@ -801,6 +804,7 @@ public class InformationElementUtilTest extends WifiBaseTest { ies, 0x1 << 4, false, + false, "[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][RSN-PSK-CCMP+TKIP]", null); } @@ -1130,6 +1134,210 @@ public class InformationElementUtilTest extends WifiBaseTest { } /** + * Test Capabilities.generateCapabilitiesString() with RSN, RSNO & RSNO2 element + * This configuration is same as a Wi-Fi 7 supported AP configured in + * WPA3-Compatibility Mode operating on the 2.4GHz/5GHz. + * Expect the function to return a string with the proper security information. + */ + @Test + public void buildCapabilities_rsnRsnoAndRsno2Element() { + //RSNE Element carries WPA-PSK (AKM: 2) + InformationElement ieRsn = new InformationElement(); + ieRsn.id = InformationElement.EID_RSN; + ieRsn.bytes = new byte[] { + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Pairwise Cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // PSK AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, + // RSN capabilities + (byte) 0x00, (byte) 0x00, + }; + + //RSNE Override Element carries SAE (AKM: 8) + InformationElement ieRsno = new InformationElement(); + ieRsno.id = InformationElement.EID_VSA; + ieRsno.bytes = new byte[] { + // RSNO (OUI type - 0x29) WFA vendor specific IE header + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x29, + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Pairwise Cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // SAE AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08, + // RSN capabilities + (byte) 0xC0, (byte) 0x00 }; + + //RSNE Override Element 2 Element carries SAE_EXT_KEY (AKM: 24) + InformationElement ieRsno2 = new InformationElement(); + ieRsno2.id = InformationElement.EID_VSA; + ieRsno2.bytes = new byte[]{ + // RSNO2 (OUI type - 0x2A) WFA vendor specific IE header + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x2A, + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Cipher suite: GCMP-256 + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x09, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // SAE-EXT-KEY AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x18, + // Padding + // RSN capabilities + (byte) 0xC0, (byte) 0x00, + }; + + InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno, ieRsno2 }; + + verifyCapabilityStringFromIes( + ies, + 0x1 << 4, + true, + true, + "[WPA2-PSK-CCMP][RSN-PSK-CCMP][RSN-SAE-CCMP][RSN-SAE_EXT_KEY-GCMP-256][MFPC][RSNO]", + null); + } + + /** + * Test Capabilities.generateCapabilitiesString() with RSN, RSNO & RSNO2 element + * This configuration is same as a Wi-Fi 7 supported AP configured in + * WPA3-Compatibility Mode operating on the 6GHz band. + * Expect the function to return a string with the proper security information. + */ + @Test + public void buildCapabilities_rsnAndRsno2Element() { + //RSNE Element carries SAE (AKM: 8) + InformationElement ieRsn = new InformationElement(); + ieRsn.id = InformationElement.EID_RSN; + ieRsn.bytes = new byte[] { + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Pairwise Cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // SAE AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08, + // RSN capabilities + (byte) 0xC0, (byte) 0x00, + }; + + //RSNE Override Element 2 Element carries SAE_EXT_KEY (AKM: 24) + InformationElement ieRsno2 = new InformationElement(); + ieRsno2.id = InformationElement.EID_VSA; + ieRsno2.bytes = new byte[]{ + // RSNO2 (OUI type - 0x2A) WFA vendor specific IE header + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x2A, + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Cipher suite: GCMP-256 + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x09, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // SAE-EXT-KEY AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x18, + // Padding + // RSN capabilities + (byte) 0xC0, (byte) 0x00, + }; + + InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno2 }; + + verifyCapabilityStringFromIes( + ies, + 0x1 << 4, + true, + true, + "[RSN-SAE-CCMP][RSN-SAE_EXT_KEY-GCMP-256][MFPR][MFPC][RSNO]", + null); + } + + /** + * Test Capabilities.generateCapabilitiesString() without RSN Overriding support. + * The AP advertise WPA2 security params in RSN IE and WPA3 security params in RSNO element. + * But without the RSN Overriding support, it is expected to return a capabilities string + * which contains only WPA2 security params. + */ + @Test + public void buildCapabilities_rsnAndRsnoElementWithoutRsnOverridingSupport() { + //RSNE Element carries WPA-PSK (AKM: 2) + InformationElement ieRsn = new InformationElement(); + ieRsn.id = InformationElement.EID_RSN; + ieRsn.bytes = new byte[] { + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Pairwise Cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // PSK AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, + // RSN capabilities + (byte) 0x00, (byte) 0x00, + }; + + //RSNE Override Element carries SAE (AKM: 8) + InformationElement ieRsno = new InformationElement(); + ieRsno.id = InformationElement.EID_VSA; + ieRsno.bytes = new byte[] { + // RSNO (OUI type - 0x29) WFA vendor specific IE header + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x29, + // RSNE Version (0x0001) + (byte) 0x01, (byte) 0x00, + // Group cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of pairwise cipher suites (1) + (byte) 0x01, (byte) 0x00, + // Pairwise Cipher suite: CCMP + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04, + // Number of AKMs (1) + (byte) 0x01, (byte) 0x00, + // SAE AKM + (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08, + // RSN capabilities + (byte) 0xC0, (byte) 0x00 }; + InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno }; + + verifyCapabilityStringFromIes( + ies, + 0x1 << 4, + true, + false, + "[WPA2-PSK-CCMP][RSN-PSK-CCMP]", + null); + } + + /** * Test Capabilities.generateCapabilitiesString() with both RSN and WPA1 IE which are malformed. * Expect the function to return a string with empty key management & pairswise cipher security * information. @@ -1148,7 +1356,7 @@ public class InformationElementUtilTest extends WifiBaseTest { (byte) 0xF2, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x50 }; InformationElement[] ies = new InformationElement[] { ieWpa, ieRsn }; - verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA][RSN]", null); + verifyCapabilityStringFromIes(ies, 0x1 << 4, false, false, "[WPA][RSN]", null); } /** @@ -1172,7 +1380,8 @@ public class InformationElementUtilTest extends WifiBaseTest { ieWps.bytes = new byte[] { (byte) 0x00, (byte) 0x50, (byte) 0xF2, (byte) 0x04 }; InformationElement[] ies = new InformationElement[] { ieWpa, ieWps }; - verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA-PSK-CCMP+TKIP][WPS]", null); + verifyCapabilityStringFromIes(ies, 0x1 << 4, false, false, "[WPA-PSK-CCMP+TKIP][WPS]", + null); } /** @@ -1253,7 +1462,7 @@ public class InformationElementUtilTest extends WifiBaseTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(new InformationElement[0], beaconCap, false, 2400, null); + capabilities.from(new InformationElement[0], beaconCap, false, false, 2400, null); String result = capabilities.generateCapabilitiesString(); assertEquals("[IBSS]", result); @@ -1270,7 +1479,7 @@ public class InformationElementUtilTest extends WifiBaseTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(new InformationElement[0], beaconCap, false, 58320, null); + capabilities.from(new InformationElement[0], beaconCap, false, false, 58320, null); String result = capabilities.generateCapabilitiesString(); assertEquals("[IBSS]", result); @@ -1287,7 +1496,7 @@ public class InformationElementUtilTest extends WifiBaseTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(new InformationElement[0], beaconCap, false, 58320, null); + capabilities.from(new InformationElement[0], beaconCap, false, false, 58320, null); String result = capabilities.generateCapabilitiesString(); assertEquals("[ESS]", result); |