summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/MacAddressUtil.java50
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java18
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java2
-rw-r--r--tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java16
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java3
6 files changed, 62 insertions, 39 deletions
diff --git a/service/java/com/android/server/wifi/MacAddressUtil.java b/service/java/com/android/server/wifi/MacAddressUtil.java
index effa931a5..a29c3fce9 100644
--- a/service/java/com/android/server/wifi/MacAddressUtil.java
+++ b/service/java/com/android/server/wifi/MacAddressUtil.java
@@ -17,7 +17,6 @@
package com.android.server.wifi;
import android.net.MacAddress;
-import android.net.wifi.WifiConfiguration;
import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
@@ -46,24 +45,22 @@ import javax.crypto.SecretKey;
public class MacAddressUtil {
private static final String TAG = "MacAddressUtil";
private static final String MAC_RANDOMIZATION_ALIAS = "MacRandSecret";
+ private static final String MAC_RANDOMIZATION_SAP_ALIAS = "MacRandSapSecret";
private static final long MAC_ADDRESS_VALID_LONG_MASK = (1L << 48) - 1;
private static final long MAC_ADDRESS_LOCALLY_ASSIGNED_MASK = 1L << 41;
private static final long MAC_ADDRESS_MULTICAST_MASK = 1L << 40;
/**
- * Computes the persistent randomized MAC of the given configuration using the given
- * hash function.
- * @param config the WifiConfiguration to compute MAC address for
+ * Computes the persistent randomized MAC using the given key and hash function.
+ * @param key the key to compute MAC address for
* @param hashFunction the hash function that will perform the MAC address computation.
* @return The persistent randomized MAC address or null if inputs are invalid.
*/
- public MacAddress calculatePersistentMacForConfiguration(WifiConfiguration config,
- Mac hashFunction) {
- if (config == null || hashFunction == null) {
+ public MacAddress calculatePersistentMac(String key, Mac hashFunction) {
+ if (key == null || hashFunction == null) {
return null;
}
- byte[] hashedBytes = hashFunction.doFinal(
- config.getSsidAndSecurityTypeString().getBytes(StandardCharsets.UTF_8));
+ byte[] hashedBytes = hashFunction.doFinal(key.getBytes(StandardCharsets.UTF_8));
ByteBuffer bf = ByteBuffer.wrap(hashedBytes);
long longFromSsid = bf.getLong();
/**
@@ -82,21 +79,16 @@ public class MacAddressUtil {
return macAddress;
}
- /**
- * Retrieves a Hash function that could be used to calculate the persistent randomized MAC
- * for a WifiConfiguration.
- * @param uid the UID of the KeyStore to get the secret of the hash function from.
- */
- public Mac obtainMacRandHashFunction(int uid) {
+ private Mac obtainMacRandHashFunctionInternal(int uid, String alias) {
try {
KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(uid);
// tries to retrieve the secret, and generate a new one if it's unavailable.
- Key key = keyStore.getKey(MAC_RANDOMIZATION_ALIAS, null);
+ Key key = keyStore.getKey(alias, null);
if (key == null) {
- key = generateAndPersistNewMacRandomizationSecret(uid);
+ key = generateAndPersistNewMacRandomizationSecret(uid, alias);
}
if (key == null) {
- Log.e(TAG, "Failed to generate secret for " + MAC_RANDOMIZATION_ALIAS);
+ Log.e(TAG, "Failed to generate secret for " + alias);
return null;
}
Mac result = Mac.getInstance("HmacSHA256");
@@ -110,16 +102,34 @@ public class MacAddressUtil {
}
/**
+ * Retrieves a Hash function that could be used to calculate the persistent randomized MAC
+ * for a WifiConfiguration for client mode.
+ * @param uid the UID of the KeyStore to get the secret of the hash function from.
+ */
+ public Mac obtainMacRandHashFunction(int uid) {
+ return obtainMacRandHashFunctionInternal(uid, MAC_RANDOMIZATION_ALIAS);
+ }
+
+ /**
+ * Retrieves a Hash function that could be used to calculate the persistent randomized MAC
+ * for a WifiConfiguration for Soft AP.
+ * @param uid the UID of the KeyStore to get the secret of the hash function from.
+ */
+ public Mac obtainMacRandHashFunctionForSap(int uid) {
+ return obtainMacRandHashFunctionInternal(uid, MAC_RANDOMIZATION_SAP_ALIAS);
+ }
+
+ /**
* Generates and returns a secret key to use for Mac randomization.
* Will also persist the generated secret inside KeyStore, accessible in the
* future with KeyGenerator#getKey.
*/
- private SecretKey generateAndPersistNewMacRandomizationSecret(int uid) {
+ private SecretKey generateAndPersistNewMacRandomizationSecret(int uid, String alias) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
keyGenerator.init(
- new KeyGenParameterSpec.Builder(MAC_RANDOMIZATION_ALIAS,
+ new KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_SIGN)
.setUid(uid)
.build());
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index c7499af3c..7cb7a4cef 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -30,6 +30,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
import android.os.Handler;
+import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
@@ -50,6 +51,7 @@ import java.util.ArrayList;
import java.util.Random;
import javax.annotation.Nullable;
+import javax.crypto.Mac;
/**
* Provides API for reading/writing soft access point configuration.
@@ -92,6 +94,8 @@ public class WifiApConfigStore {
private final String mApConfigFile;
private final BackupManagerProxy mBackupManagerProxy;
private final FrameworkFacade mFrameworkFacade;
+ private final MacAddressUtil mMacAddressUtil;
+ private final Mac mMac;
private boolean mRequiresApBandConversion = false;
WifiApConfigStore(Context context, WifiInjector wifiInjector, Handler handler,
@@ -143,6 +147,12 @@ public class WifiApConfigStore {
filter.addAction(ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT);
mContext.registerReceiver(
mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
+ mMacAddressUtil = mWifiInjector.getMacAddressUtil();
+ mMac = mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID);
+ if (mMac == null) {
+ Log.wtf(TAG, "Failed to obtain secret for SAP MAC randomization."
+ + " All randomized MAC addresses are lost!");
+ }
}
private final BroadcastReceiver mBroadcastReceiver =
@@ -413,7 +423,13 @@ public class WifiApConfigStore {
config = new WifiConfiguration(config);
if (config.BSSID == null && context.getResources().getBoolean(
R.bool.config_wifi_ap_mac_randomization_supported)) {
- config.BSSID = MacAddress.createRandomUnicastAddress().toString();
+ MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(config.SSID, mMac);
+ if (macAddress == null) {
+ Log.e(TAG, "Failed to calculate MAC from SSID. "
+ + "Generating new random MAC instead.");
+ macAddress = MacAddress.createRandomUnicastAddress();
+ }
+ config.BSSID = macAddress.toString();
}
return config;
}
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 958a9f1b0..82d799081 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -572,7 +572,7 @@ public class WifiConfigManager {
mRandomizedMacAddressMapping.remove(config.getSsidAndSecurityTypeString());
}
}
- return mMacAddressUtil.calculatePersistentMacForConfiguration(config, mMac);
+ return mMacAddressUtil.calculatePersistentMac(config.getSsidAndSecurityTypeString(), mMac);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java b/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java
index 331725c14..1e04c8643 100644
--- a/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java
@@ -49,23 +49,21 @@ public class MacAddressUtilTest extends WifiBaseTest {
}
/**
- * Verifies that calculatePersistentMacForConfiguration valid randomized MACs.
+ * Verifies that calculatePersistentMac generate valid randomized MACs.
*/
@Test
- public void testCalculatePersistentMacForConfiguration() {
+ public void testCalculatePersistentMac() {
// verify null inputs
- assertNull(mMacAddressUtil.calculatePersistentMacForConfiguration(null, null));
+ assertNull(mMacAddressUtil.calculatePersistentMac(null, null));
Random rand = new Random();
// Verify that a the MAC address calculated is valid
for (int i = 0; i < 10; i++) {
- WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
-
byte[] bytes = new byte[32];
rand.nextBytes(bytes);
when(mMac.doFinal(any())).thenReturn(bytes);
- MacAddress macAddress = mMacAddressUtil.calculatePersistentMacForConfiguration(
- config, mMac);
+ MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(
+ "TEST_SSID_AND_SECURITY_TYPE_" + i, mMac);
assertTrue(WifiConfiguration.isValidMacAddressForRandomization(macAddress));
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 3d78e1e46..f150bf797 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -84,6 +84,8 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
private static final String TEST_STRING_UTF8_WITH_32_BYTES = "ΣωκράτηςΣωκράτης";
private static final String TEST_STRING_UTF8_WITH_33_BYTES = "一片汪洋大海中的一條魚";
private static final String TEST_STRING_UTF8_WITH_34_BYTES = "Ευπροσηγοροςγινου";
+ private static final MacAddress TEST_RANDOMIZED_MAC =
+ MacAddress.fromString("d2:11:19:34:a5:20");
@Mock private Context mContext;
@Mock private WifiInjector mWifiInjector;
@@ -96,6 +98,7 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
@Mock private ApplicationInfo mMockApplInfo;
private BroadcastReceiver mBroadcastReceiver;
@Mock private NotificationManager mNotificationManager;
+ @Mock private MacAddressUtil mMacAddressUtil;
private ArrayList<Integer> mKnownGood2GChannelList;
@Before
@@ -132,6 +135,8 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
mKnownGood2GChannelList = new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6));
mRandom = new Random();
+ when(mWifiInjector.getMacAddressUtil()).thenReturn(mMacAddressUtil);
+ when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(TEST_RANDOMIZED_MAC);
}
@After
@@ -591,14 +596,9 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
WifiConfiguration baseConfig = new WifiConfiguration();
WifiApConfigStore store = createWifiApConfigStore();
- WifiConfiguration config1 = store.randomizeBssidIfUnset(mContext, baseConfig);
- WifiConfiguration config2 = store.randomizeBssidIfUnset(mContext, baseConfig);
-
- assertThat(config1.BSSID).isNotNull();
- assertThat(config2.BSSID).isNotNull();
- MacAddress mac1 = MacAddress.fromString(config1.BSSID);
- MacAddress mac2 = MacAddress.fromString(config2.BSSID);
- assertThat(mac1).isNotEqualTo(mac2);
+ WifiConfiguration config = store.randomizeBssidIfUnset(mContext, baseConfig);
+
+ assertEquals(TEST_RANDOMIZED_MAC.toString(), config.BSSID);
}
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index e99224512..895a169a1 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -222,8 +222,7 @@ public class WifiConfigManagerTest extends WifiBaseTest {
.thenReturn(false);
when(mWifiInjector.getCarrierNetworkConfig()).thenReturn(mCarrierNetworkConfig);
when(mWifiInjector.getMacAddressUtil()).thenReturn(mMacAddressUtil);
- when(mMacAddressUtil.calculatePersistentMacForConfiguration(any(), any()))
- .thenReturn(TEST_RANDOMIZED_MAC);
+ when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(TEST_RANDOMIZED_MAC);
mTelephonyUtil = new TelephonyUtil(mTelephonyManager, mSubscriptionManager);
createWifiConfigManager();