OSDN Git Service

MacAddress: Use SecureRandom and add a 46 bit randomized MAC generator
authorJong Wook Kim <jongwook@google.com>
Thu, 1 Feb 2018 03:03:19 +0000 (19:03 -0800)
committerJong Wook Kim <jongwook@google.com>
Wed, 7 Feb 2018 01:28:46 +0000 (01:28 +0000)
Use SecureRandom instead of Random since Random is time based and can
increase the chance of generating same MAC address across multiple
devices.

createRandomUnicastAddress should randomize all bits of the address,
except for locally assigned bit and unicast bit. The previous method
that only randomizes NIC and use Google Base OUI is renamed to
createRandomUnicastAddressWithGoogleBase.

Bug: 72450936
Test: runtest frameworks-net
Change-Id: Icda650638c2c1c9fd90d509a87e86347c0e05f2d

core/java/android/net/MacAddress.java
tests/net/java/android/net/MacAddressTest.java

index 287bdc8..74d6470 100644 (file)
@@ -26,6 +26,7 @@ import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.security.SecureRandom;
 import java.util.Arrays;
 import java.util.Random;
 
@@ -329,16 +330,34 @@ public final class MacAddress implements Parcelable {
 
     /**
      * Returns a generated MAC address whose 24 least significant bits constituting the
-     * NIC part of the address are randomly selected.
+     * NIC part of the address are randomly selected and has Google OUI base.
      *
      * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
      *
-     * @return a random locally assigned MacAddress.
+     * @return a random locally assigned, unicast MacAddress with Google OUI.
+     *
+     * @hide
+     */
+    public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() {
+        return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom());
+    }
+
+    /**
+     * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the
+     * unicast bit, are randomly selected.
+     *
+     * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
+     *
+     * @return a random locally assigned, unicast MacAddress.
      *
      * @hide
      */
     public static @NonNull MacAddress createRandomUnicastAddress() {
-        return createRandomUnicastAddress(BASE_GOOGLE_MAC, new Random());
+        SecureRandom r = new SecureRandom();
+        long addr = r.nextLong() & VALID_LONG_MASK;
+        addr |= LOCALLY_ASSIGNED_MASK;
+        addr &= ~MULTICAST_MASK;
+        return new MacAddress(addr);
     }
 
     /**
@@ -355,8 +374,8 @@ public final class MacAddress implements Parcelable {
      */
     public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) {
         long addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong());
-        addr = addr | LOCALLY_ASSIGNED_MASK;
-        addr = addr & ~MULTICAST_MASK;
+        addr |= LOCALLY_ASSIGNED_MASK;
+        addr &= ~MULTICAST_MASK;
         return new MacAddress(addr);
     }
 
index 9aad413..04266c5 100644 (file)
@@ -172,7 +172,7 @@ public class MacAddressTest {
         final int iterations = 1000;
         final String expectedAndroidOui = "da:a1:19";
         for (int i = 0; i < iterations; i++) {
-            MacAddress mac = MacAddress.createRandomUnicastAddress();
+            MacAddress mac = MacAddress.createRandomUnicastAddressWithGoogleBase();
             String stringRepr = mac.toString();
 
             assertTrue(stringRepr + " expected to be a locally assigned address",
@@ -195,6 +195,15 @@ public class MacAddressTest {
             assertTrue(stringRepr + " expected to begin with " + expectedLocalOui,
                     stringRepr.startsWith(expectedLocalOui));
         }
+
+        for (int i = 0; i < iterations; i++) {
+            MacAddress mac = MacAddress.createRandomUnicastAddress();
+            String stringRepr = mac.toString();
+
+            assertTrue(stringRepr + " expected to be a locally assigned address",
+                    mac.isLocallyAssigned());
+            assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType());
+        }
     }
 
     @Test