Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +15 −29 Original line number Diff line number Diff line Loading @@ -173,7 +173,6 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.StringJoiner; import java.util.concurrent.CountDownLatch; Loading Loading @@ -234,7 +233,6 @@ public class LockSettingsService extends ILockSettings.Stub { private final SynchronizedStrongAuthTracker mStrongAuthTracker; private final BiometricDeferredQueue mBiometricDeferredQueue; private final LongSparseArray<byte[]> mGatekeeperPasswords; private final Random mRandom; private final NotificationManager mNotificationManager; protected final UserManager mUserManager; Loading Loading @@ -348,23 +346,17 @@ public class LockSettingsService extends ILockSettings.Stub { } private LockscreenCredential generateRandomProfilePassword() { byte[] randomLockSeed = new byte[] {}; try { randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40); byte[] randomLockSeed = SecureRandomUtils.randomBytes(40); char[] newPasswordChars = HexEncoding.encode(randomLockSeed); byte[] newPassword = new byte[newPasswordChars.length]; for (int i = 0; i < newPasswordChars.length; i++) { newPassword[i] = (byte) newPasswordChars[i]; } LockscreenCredential credential = LockscreenCredential.createManagedPassword(newPassword); LockscreenCredential credential = LockscreenCredential.createManagedPassword(newPassword); Arrays.fill(newPasswordChars, '\u0000'); Arrays.fill(newPassword, (byte) 0); Arrays.fill(randomLockSeed, (byte) 0); return credential; } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("Fail to generate profile password", e); } } /** Loading Loading @@ -597,7 +589,6 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuthTracker = injector.getStrongAuthTracker(); mStrongAuthTracker.register(mStrongAuth); mGatekeeperPasswords = new LongSparseArray<>(); mRandom = new SecureRandom(); mSpManager = injector.getSyntheticPasswordManager(mStorage); mManagedProfilePasswordCache = injector.getManagedProfilePasswordCache(mJavaKeyStore); Loading Loading @@ -1752,14 +1743,9 @@ public class LockSettingsService extends ILockSettings.Stub { private String getSalt(int userId) { long salt = getLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, 0, userId); if (salt == 0) { try { salt = SecureRandom.getInstance("SHA1PRNG").nextLong(); salt = SecureRandomUtils.randomLong(); setLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, salt, userId); Slog.v(TAG, "Initialized lock password salt for user: " + userId); } catch (NoSuchAlgorithmException e) { // Throw an exception rather than storing a password we'll never be able to recover throw new IllegalStateException("Couldn't get SecureRandom number", e); } } return Long.toHexString(salt); } Loading Loading @@ -2644,7 +2630,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mGatekeeperPasswords) { while (handle == 0L || mGatekeeperPasswords.get(handle) != null) { handle = mRandom.nextLong(); handle = SecureRandomUtils.randomLong(); } mGatekeeperPasswords.put(handle, gatekeeperPassword); } Loading services/core/java/com/android/server/locksettings/SecureRandomUtils.java 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.locksettings; import java.security.SecureRandom; /** Utilities using a static SecureRandom */ public class SecureRandomUtils { private static final SecureRandom RNG = new SecureRandom(); /** Use SecureRandom to generate `length` random bytes */ public static byte[] randomBytes(int length) { byte[] res = new byte[length]; RNG.nextBytes(res); return res; } /** Use SecureRandom to generate a random long */ public static long randomLong() { return RNG.nextLong(); } } services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +15 −24 Original line number Diff line number Diff line Loading @@ -59,8 +59,6 @@ import libcore.util.HexEncoding; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; Loading Loading @@ -284,8 +282,10 @@ class SyntheticPasswordManager { */ static SyntheticPassword create() { SyntheticPassword result = new SyntheticPassword(SYNTHETIC_PASSWORD_VERSION_V3); byte[] escrowSplit0 = secureRandom(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit1 = secureRandom(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit0 = SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit1 = SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); result.recreate(escrowSplit0, escrowSplit1); byte[] encrypteEscrowSplit0 = SyntheticPasswordCrypto.encrypt(result.mSyntheticPassword, PERSONALIZATION_E0, escrowSplit0); Loading Loading @@ -347,7 +347,7 @@ class SyntheticPasswordManager { result.scryptLogR = PASSWORD_SCRYPT_LOG_R; result.scryptLogP = PASSWORD_SCRYPT_LOG_P; result.credentialType = credentialType; result.salt = secureRandom(PASSWORD_SALT_LENGTH); result.salt = SecureRandomUtils.randomBytes(PASSWORD_SALT_LENGTH); return result; } Loading Loading @@ -552,7 +552,7 @@ class SyntheticPasswordManager { throw new IllegalArgumentException("Invalid key size for weaver"); } if (value == null) { value = secureRandom(mWeaverConfig.valueSize); value = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); } try { mWeaver.write(slot, key, value); Loading Loading @@ -1039,9 +1039,9 @@ class SyntheticPasswordManager { } TokenData tokenData = new TokenData(); tokenData.mType = type; final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH); final byte[] secdiscardable = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); if (isWeaverAvailable()) { tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize); tokenData.weaverSecret = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret, PERSONALIZATION_WEAVER_TOKEN, secdiscardable); } else { Loading Loading @@ -1510,7 +1510,7 @@ class SyntheticPasswordManager { * been created. */ private byte[] createSecdiscardable(long protectorId, int userId) { byte[] data = secureRandom(SECDISCARDABLE_LENGTH); byte[] data = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); saveSecdiscardable(protectorId, data, userId); return data; } Loading Loading @@ -1624,28 +1624,19 @@ class SyntheticPasswordManager { } private static long generateProtectorId() { SecureRandom rng = new SecureRandom(); long result; do { result = rng.nextLong(); } while (result == NULL_PROTECTOR_ID); while (true) { final long result = SecureRandomUtils.randomLong(); if (result != NULL_PROTECTOR_ID) { return result; } } } @VisibleForTesting static int fakeUserId(int userId) { return 100000 + userId; } protected static byte[] secureRandom(int length) { try { return SecureRandom.getInstance("SHA1PRNG").generateSeed(length); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } private String getProtectorKeyAlias(long protectorId) { return TextUtils.formatSimple("%s%x", PROTECTOR_KEY_ALIAS_PREFIX, protectorId); } Loading Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +15 −29 Original line number Diff line number Diff line Loading @@ -173,7 +173,6 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.StringJoiner; import java.util.concurrent.CountDownLatch; Loading Loading @@ -234,7 +233,6 @@ public class LockSettingsService extends ILockSettings.Stub { private final SynchronizedStrongAuthTracker mStrongAuthTracker; private final BiometricDeferredQueue mBiometricDeferredQueue; private final LongSparseArray<byte[]> mGatekeeperPasswords; private final Random mRandom; private final NotificationManager mNotificationManager; protected final UserManager mUserManager; Loading Loading @@ -348,23 +346,17 @@ public class LockSettingsService extends ILockSettings.Stub { } private LockscreenCredential generateRandomProfilePassword() { byte[] randomLockSeed = new byte[] {}; try { randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40); byte[] randomLockSeed = SecureRandomUtils.randomBytes(40); char[] newPasswordChars = HexEncoding.encode(randomLockSeed); byte[] newPassword = new byte[newPasswordChars.length]; for (int i = 0; i < newPasswordChars.length; i++) { newPassword[i] = (byte) newPasswordChars[i]; } LockscreenCredential credential = LockscreenCredential.createManagedPassword(newPassword); LockscreenCredential credential = LockscreenCredential.createManagedPassword(newPassword); Arrays.fill(newPasswordChars, '\u0000'); Arrays.fill(newPassword, (byte) 0); Arrays.fill(randomLockSeed, (byte) 0); return credential; } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("Fail to generate profile password", e); } } /** Loading Loading @@ -597,7 +589,6 @@ public class LockSettingsService extends ILockSettings.Stub { mStrongAuthTracker = injector.getStrongAuthTracker(); mStrongAuthTracker.register(mStrongAuth); mGatekeeperPasswords = new LongSparseArray<>(); mRandom = new SecureRandom(); mSpManager = injector.getSyntheticPasswordManager(mStorage); mManagedProfilePasswordCache = injector.getManagedProfilePasswordCache(mJavaKeyStore); Loading Loading @@ -1752,14 +1743,9 @@ public class LockSettingsService extends ILockSettings.Stub { private String getSalt(int userId) { long salt = getLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, 0, userId); if (salt == 0) { try { salt = SecureRandom.getInstance("SHA1PRNG").nextLong(); salt = SecureRandomUtils.randomLong(); setLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, salt, userId); Slog.v(TAG, "Initialized lock password salt for user: " + userId); } catch (NoSuchAlgorithmException e) { // Throw an exception rather than storing a password we'll never be able to recover throw new IllegalStateException("Couldn't get SecureRandom number", e); } } return Long.toHexString(salt); } Loading Loading @@ -2644,7 +2630,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mGatekeeperPasswords) { while (handle == 0L || mGatekeeperPasswords.get(handle) != null) { handle = mRandom.nextLong(); handle = SecureRandomUtils.randomLong(); } mGatekeeperPasswords.put(handle, gatekeeperPassword); } Loading
services/core/java/com/android/server/locksettings/SecureRandomUtils.java 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.locksettings; import java.security.SecureRandom; /** Utilities using a static SecureRandom */ public class SecureRandomUtils { private static final SecureRandom RNG = new SecureRandom(); /** Use SecureRandom to generate `length` random bytes */ public static byte[] randomBytes(int length) { byte[] res = new byte[length]; RNG.nextBytes(res); return res; } /** Use SecureRandom to generate a random long */ public static long randomLong() { return RNG.nextLong(); } }
services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +15 −24 Original line number Diff line number Diff line Loading @@ -59,8 +59,6 @@ import libcore.util.HexEncoding; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; Loading Loading @@ -284,8 +282,10 @@ class SyntheticPasswordManager { */ static SyntheticPassword create() { SyntheticPassword result = new SyntheticPassword(SYNTHETIC_PASSWORD_VERSION_V3); byte[] escrowSplit0 = secureRandom(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit1 = secureRandom(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit0 = SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); byte[] escrowSplit1 = SecureRandomUtils.randomBytes(SYNTHETIC_PASSWORD_SECURITY_STRENGTH); result.recreate(escrowSplit0, escrowSplit1); byte[] encrypteEscrowSplit0 = SyntheticPasswordCrypto.encrypt(result.mSyntheticPassword, PERSONALIZATION_E0, escrowSplit0); Loading Loading @@ -347,7 +347,7 @@ class SyntheticPasswordManager { result.scryptLogR = PASSWORD_SCRYPT_LOG_R; result.scryptLogP = PASSWORD_SCRYPT_LOG_P; result.credentialType = credentialType; result.salt = secureRandom(PASSWORD_SALT_LENGTH); result.salt = SecureRandomUtils.randomBytes(PASSWORD_SALT_LENGTH); return result; } Loading Loading @@ -552,7 +552,7 @@ class SyntheticPasswordManager { throw new IllegalArgumentException("Invalid key size for weaver"); } if (value == null) { value = secureRandom(mWeaverConfig.valueSize); value = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); } try { mWeaver.write(slot, key, value); Loading Loading @@ -1039,9 +1039,9 @@ class SyntheticPasswordManager { } TokenData tokenData = new TokenData(); tokenData.mType = type; final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH); final byte[] secdiscardable = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); if (isWeaverAvailable()) { tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize); tokenData.weaverSecret = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize); tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret, PERSONALIZATION_WEAVER_TOKEN, secdiscardable); } else { Loading Loading @@ -1510,7 +1510,7 @@ class SyntheticPasswordManager { * been created. */ private byte[] createSecdiscardable(long protectorId, int userId) { byte[] data = secureRandom(SECDISCARDABLE_LENGTH); byte[] data = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH); saveSecdiscardable(protectorId, data, userId); return data; } Loading Loading @@ -1624,28 +1624,19 @@ class SyntheticPasswordManager { } private static long generateProtectorId() { SecureRandom rng = new SecureRandom(); long result; do { result = rng.nextLong(); } while (result == NULL_PROTECTOR_ID); while (true) { final long result = SecureRandomUtils.randomLong(); if (result != NULL_PROTECTOR_ID) { return result; } } } @VisibleForTesting static int fakeUserId(int userId) { return 100000 + userId; } protected static byte[] secureRandom(int length) { try { return SecureRandom.getInstance("SHA1PRNG").generateSeed(length); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } private String getProtectorKeyAlias(long protectorId) { return TextUtils.formatSimple("%s%x", PROTECTOR_KEY_ALIAS_PREFIX, protectorId); } Loading