1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.locksettings; 18 19 import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; 20 import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; 21 import static android.Manifest.permission.MANAGE_BIOMETRIC; 22 import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS; 23 import static android.Manifest.permission.SET_INITIAL_LOCK; 24 import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT; 25 import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG; 26 import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_DETAIL; 27 import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_MESSAGE; 28 import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_TITLE; 29 import static android.content.Context.KEYGUARD_SERVICE; 30 import static android.content.Intent.ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED; 31 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 32 import static android.os.UserHandle.USER_ALL; 33 import static android.os.UserHandle.USER_SYSTEM; 34 35 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; 36 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN; 37 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; 38 import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY; 39 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; 40 import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE; 41 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; 42 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE; 43 import static com.android.internal.widget.LockPatternUtils.USER_FRP; 44 import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE; 45 import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE; 46 import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW; 47 import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled; 48 import static com.android.internal.widget.LockPatternUtils.isSpecialUserId; 49 import static com.android.internal.widget.LockPatternUtils.pinOrPasswordQualityToCredentialType; 50 import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential; 51 import static com.android.server.locksettings.SyntheticPasswordManager.TOKEN_TYPE_STRONG; 52 import static com.android.server.locksettings.SyntheticPasswordManager.TOKEN_TYPE_WEAK; 53 54 import android.Manifest; 55 import android.annotation.NonNull; 56 import android.annotation.Nullable; 57 import android.annotation.RequiresPermission; 58 import android.annotation.UserIdInt; 59 import android.app.ActivityManager; 60 import android.app.IActivityManager; 61 import android.app.KeyguardManager; 62 import android.app.Notification; 63 import android.app.NotificationManager; 64 import android.app.PendingIntent; 65 import android.app.RemoteLockscreenValidationResult; 66 import android.app.RemoteLockscreenValidationSession; 67 import android.app.admin.DevicePolicyManager; 68 import android.app.admin.DevicePolicyManagerInternal; 69 import android.app.admin.DeviceStateCache; 70 import android.app.admin.PasswordMetrics; 71 import android.app.trust.IStrongAuthTracker; 72 import android.app.trust.TrustManager; 73 import android.content.BroadcastReceiver; 74 import android.content.ContentResolver; 75 import android.content.Context; 76 import android.content.Intent; 77 import android.content.IntentFilter; 78 import android.content.pm.PackageManager; 79 import android.content.pm.UserInfo; 80 import android.content.pm.UserProperties; 81 import android.content.res.Resources; 82 import android.database.ContentObserver; 83 import android.database.sqlite.SQLiteDatabase; 84 import android.hardware.authsecret.IAuthSecret; 85 import android.hardware.biometrics.BiometricManager; 86 import android.hardware.face.Face; 87 import android.hardware.face.FaceManager; 88 import android.hardware.fingerprint.Fingerprint; 89 import android.hardware.fingerprint.FingerprintManager; 90 import android.net.Uri; 91 import android.os.Binder; 92 import android.os.Bundle; 93 import android.os.Handler; 94 import android.os.IBinder; 95 import android.os.IProgressListener; 96 import android.os.Process; 97 import android.os.RemoteException; 98 import android.os.ResultReceiver; 99 import android.os.ServiceManager; 100 import android.os.ShellCallback; 101 import android.os.SystemClock; 102 import android.os.SystemProperties; 103 import android.os.UserHandle; 104 import android.os.UserManager; 105 import android.os.storage.ICeStorageLockEventListener; 106 import android.os.storage.IStorageManager; 107 import android.os.storage.StorageManager; 108 import android.os.storage.StorageManagerInternal; 109 import android.provider.DeviceConfig; 110 import android.provider.Settings; 111 import android.security.AndroidKeyStoreMaintenance; 112 import android.security.KeyStoreAuthorization; 113 import android.security.keystore.KeyProperties; 114 import android.security.keystore.KeyProtection; 115 import android.security.keystore.recovery.KeyChainProtectionParams; 116 import android.security.keystore.recovery.KeyChainSnapshot; 117 import android.security.keystore.recovery.RecoveryCertPath; 118 import android.security.keystore.recovery.WrappedApplicationKey; 119 import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; 120 import android.security.keystore2.AndroidKeyStoreProvider; 121 import android.service.gatekeeper.IGateKeeperService; 122 import android.service.notification.StatusBarNotification; 123 import android.system.keystore2.Domain; 124 import android.text.TextUtils; 125 import android.util.ArrayMap; 126 import android.util.ArraySet; 127 import android.util.Log; 128 import android.util.LongSparseArray; 129 import android.util.Pair; 130 import android.util.Slog; 131 import android.util.SparseArray; 132 import android.util.SparseIntArray; 133 134 import com.android.internal.R; 135 import com.android.internal.annotations.GuardedBy; 136 import com.android.internal.annotations.VisibleForTesting; 137 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 138 import com.android.internal.notification.SystemNotificationChannels; 139 import com.android.internal.pm.RoSystemFeatures; 140 import com.android.internal.util.ArrayUtils; 141 import com.android.internal.util.DumpUtils; 142 import com.android.internal.util.IndentingPrintWriter; 143 import com.android.internal.util.Preconditions; 144 import com.android.internal.widget.ICheckCredentialProgressCallback; 145 import com.android.internal.widget.ILockSettings; 146 import com.android.internal.widget.IWeakEscrowTokenActivatedListener; 147 import com.android.internal.widget.IWeakEscrowTokenRemovedListener; 148 import com.android.internal.widget.LockPatternUtils; 149 import com.android.internal.widget.LockSettingsInternal; 150 import com.android.internal.widget.LockSettingsStateListener; 151 import com.android.internal.widget.LockscreenCredential; 152 import com.android.internal.widget.RebootEscrowListener; 153 import com.android.internal.widget.VerifyCredentialResponse; 154 import com.android.server.LocalServices; 155 import com.android.server.ServiceThread; 156 import com.android.server.SystemService; 157 import com.android.server.locksettings.LockSettingsStorage.PersistentData; 158 import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult; 159 import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPassword; 160 import com.android.server.locksettings.SyntheticPasswordManager.TokenType; 161 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; 162 import com.android.server.pm.UserManagerInternal; 163 import com.android.server.utils.Slogf; 164 import com.android.server.wm.WindowManagerInternal; 165 166 import libcore.util.HexEncoding; 167 168 import java.io.FileDescriptor; 169 import java.io.FileNotFoundException; 170 import java.io.IOException; 171 import java.io.PrintWriter; 172 import java.security.GeneralSecurityException; 173 import java.security.InvalidAlgorithmParameterException; 174 import java.security.InvalidKeyException; 175 import java.security.KeyStore; 176 import java.security.KeyStoreException; 177 import java.security.NoSuchAlgorithmException; 178 import java.security.SecureRandom; 179 import java.security.UnrecoverableKeyException; 180 import java.security.cert.CertificateException; 181 import java.text.SimpleDateFormat; 182 import java.util.ArrayList; 183 import java.util.Arrays; 184 import java.util.Date; 185 import java.util.Enumeration; 186 import java.util.List; 187 import java.util.Map; 188 import java.util.NoSuchElementException; 189 import java.util.Objects; 190 import java.util.Set; 191 import java.util.StringJoiner; 192 import java.util.concurrent.CopyOnWriteArrayList; 193 import java.util.concurrent.CountDownLatch; 194 import java.util.concurrent.TimeUnit; 195 196 import javax.crypto.BadPaddingException; 197 import javax.crypto.Cipher; 198 import javax.crypto.IllegalBlockSizeException; 199 import javax.crypto.KeyGenerator; 200 import javax.crypto.NoSuchPaddingException; 201 import javax.crypto.SecretKey; 202 import javax.crypto.spec.GCMParameterSpec; 203 204 /** 205 * LockSettingsService (LSS) mainly has the following responsibilities: 206 * <p> 207 * <ul> 208 * <li>Provide APIs to verify and change the Lock Screen Knowledge Factor (LSKF) ("lockscreen 209 * credential") of each user. Unlock users when their correct LSKF is given.</li> 210 * 211 * <li>Store other lockscreen related settings, such as some Keyguard (UI) settings.</li> 212 * 213 * <li>Manage each user's synthetic password (SP), which is their main cryptographic secret. 214 * See {@link SyntheticPasswordManager}.</li> 215 * 216 * <li>Protect each user's SP using their LSKF. Use the Gatekeeper or Weaver HAL to ensure that 217 * guesses of the LSKF are ratelimited by the TEE or secure element.</li> 218 * 219 * <li>Protect each user's data using their SP. For example, use the SP to encrypt/decrypt the 220 * user's credential-encrypted (CE) key for file-based encryption (FBE).</li> 221 * 222 * <li>Generate, protect, and use unified profile passwords.</li> 223 * 224 * <li>Support unlocking the SP by alternative means: resume-on-reboot (reboot escrow) for easier 225 * OTA updates, and escrow tokens when set up by the Device Policy Controller (DPC).</li> 226 * 227 * <li>Implement part of the Factory Reset Protection (FRP) and Repair Mode features by storing 228 * the information needed to verify a user's LSKF on the persist or metadata partition.</li> 229 * 230 * <li>Support insider attack resistance using the AuthSecret HAL.</li> 231 * 232 * <li>Implement "recoverable keystore", a feature that enables end-to-end encrypted backups. 233 * See {@link android.security.keystore.recovery.RecoveryController}.</li> 234 * </ul> 235 * <p> 236 * The main clients of LockSettingsService are Keyguard (i.e. the lockscreen UI, which is part of 237 * System UI), the Settings app (com.android.settings), and other parts of system_server. Most 238 * methods are protected by ACCESS_KEYGUARD_SECURE_STORAGE which only system processes can have. 239 * 240 * @hide 241 */ 242 public class LockSettingsService extends ILockSettings.Stub { 243 private static final String TAG = "LockSettingsService"; 244 private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE; 245 private static final String BIOMETRIC_PERMISSION = MANAGE_BIOMETRIC; 246 247 private static final int PROFILE_KEY_IV_SIZE = 12; 248 private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge"; 249 private static final String PREV_LSKF_BASED_PROTECTOR_ID_KEY = "prev-sp-handle"; 250 private static final String LSKF_LAST_CHANGED_TIME_KEY = "sp-handle-ts"; 251 private static final String USER_SERIAL_NUMBER_KEY = "serial-number"; 252 253 private static final String MIGRATED_FRP2 = "migrated_frp2"; 254 private static final String MIGRATED_KEYSTORE_NS = "migrated_keystore_namespace"; 255 private static final String MIGRATED_SP_FULL = "migrated_all_users_to_sp_and_bound_keys"; 256 private static final String MIGRATED_WEAVER_DISABLED_ON_UNSECURED_USERS = 257 "migrated_weaver_disabled_on_unsecured_users"; 258 // Note: some other migrated_* strings used to be used and may exist in the database already. 259 260 // Duration that LockSettingsService will store the gatekeeper password for. This allows 261 // multiple biometric enrollments without prompting the user to enter their password via 262 // ConfirmLockPassword/ConfirmLockPattern multiple times. This needs to be at least the duration 263 // from the start of the first biometric sensor's enrollment to the start of the last biometric 264 // sensor's enrollment. If biometric enrollment requests a password handle that has expired, the 265 // user's credential must be presented again, e.g. via ConfirmLockPattern/ConfirmLockPassword. 266 private static final int GK_PW_HANDLE_STORE_DURATION_MS = 10 * 60 * 1000; // 10 minutes 267 268 private static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_"; 269 private static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_"; 270 271 private static final int HEADLESS_VENDOR_AUTH_SECRET_LENGTH = 32; 272 273 // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this 274 // Do not call into ActivityManager while holding mSpManager lock. 275 private final Object mSeparateChallengeLock = new Object(); 276 277 private final DeviceProvisionedObserver mDeviceProvisionedObserver = 278 new DeviceProvisionedObserver(); 279 280 private final Injector mInjector; 281 private final Context mContext; 282 @VisibleForTesting 283 protected final Handler mHandler; 284 @VisibleForTesting 285 protected final LockSettingsStorage mStorage; 286 private final LockSettingsStrongAuth mStrongAuth; 287 private final SynchronizedStrongAuthTracker mStrongAuthTracker; 288 private final BiometricDeferredQueue mBiometricDeferredQueue; 289 private final LongSparseArray<byte[]> mGatekeeperPasswords; 290 291 private final NotificationManager mNotificationManager; 292 protected final UserManager mUserManager; 293 private final IStorageManager mStorageManager; 294 private final IActivityManager mActivityManager; 295 private final SyntheticPasswordManager mSpManager; 296 297 private final KeyStore mKeyStore; 298 private final KeyStoreAuthorization mKeyStoreAuthorization; 299 private final RecoverableKeyStoreManager mRecoverableKeyStoreManager; 300 private final UnifiedProfilePasswordCache mUnifiedProfilePasswordCache; 301 302 private final RebootEscrowManager mRebootEscrowManager; 303 304 // Locking order is mUserCreationAndRemovalLock -> mSpManager. 305 private final Object mUserCreationAndRemovalLock = new Object(); 306 // These two arrays are only used at boot time. To save memory, they are set to null near the 307 // end of the boot, when onThirdPartyAppsStarted() is called. 308 @GuardedBy("mUserCreationAndRemovalLock") 309 private SparseIntArray mEarlyCreatedUsers = new SparseIntArray(); 310 @GuardedBy("mUserCreationAndRemovalLock") 311 private SparseIntArray mEarlyRemovedUsers = new SparseIntArray(); 312 @GuardedBy("mUserCreationAndRemovalLock") 313 private boolean mThirdPartyAppsStarted; 314 315 // This list contains the (protectorId, userId) of any protectors that were by replaced by a 316 // migration and should be destroyed once rollback to the old build is no longer possible. 317 private ArrayList<Pair<Long, Integer>> mProtectorsToDestroyOnBootCompleted = new ArrayList<>(); 318 319 // Current password metrics for all secured users on the device. Updated when user unlocks the 320 // device or changes password. Removed if user is stopped with its CE key evicted. 321 @GuardedBy("this") 322 private final SparseArray<PasswordMetrics> mUserPasswordMetrics = new SparseArray<>(); 323 @VisibleForTesting 324 protected boolean mHasSecureLockScreen; 325 326 @VisibleForTesting 327 protected final Object mHeadlessAuthSecretLock = new Object(); 328 329 @VisibleForTesting 330 @GuardedBy("mHeadlessAuthSecretLock") 331 protected byte[] mAuthSecret; 332 333 protected IGateKeeperService mGateKeeperService; 334 protected IAuthSecret mAuthSecretService; 335 336 /** 337 * The UIDs that are used for system credential storage in keystore. 338 */ 339 private static final int[] SYSTEM_CREDENTIAL_UIDS = { 340 Process.VPN_UID, Process.ROOT_UID, Process.SYSTEM_UID}; 341 342 private final CopyOnWriteArrayList<LockSettingsStateListener> mLockSettingsStateListeners = 343 new CopyOnWriteArrayList<>(); 344 345 private final StorageManagerInternal mStorageManagerInternal; 346 347 private final Object mGcWorkToken = new Object(); 348 349 // This class manages life cycle events for encrypted users on File Based Encryption (FBE) 350 // devices. The most basic of these is to show/hide notifications about missing features until 351 // the user unlocks the account and credential-encrypted storage is available. 352 public static final class Lifecycle extends SystemService { 353 private LockSettingsService mLockSettingsService; 354 Lifecycle(Context context)355 public Lifecycle(Context context) { 356 super(context); 357 } 358 359 @Override onStart()360 public void onStart() { 361 AndroidKeyStoreProvider.install(); 362 mLockSettingsService = new LockSettingsService(getContext()); 363 publishBinderService("lock_settings", mLockSettingsService); 364 } 365 366 @Override onBootPhase(int phase)367 public void onBootPhase(int phase) { 368 super.onBootPhase(phase); 369 mLockSettingsService.onBootPhase(phase); 370 } 371 372 @Override onUserStarting(@onNull TargetUser user)373 public void onUserStarting(@NonNull TargetUser user) { 374 mLockSettingsService.onUserStarting(user.getUserIdentifier()); 375 } 376 377 @Override onUserUnlocking(@onNull TargetUser user)378 public void onUserUnlocking(@NonNull TargetUser user) { 379 mLockSettingsService.onUserUnlocking(user.getUserIdentifier()); 380 } 381 382 @Override onUserStopped(@onNull TargetUser user)383 public void onUserStopped(@NonNull TargetUser user) { 384 mLockSettingsService.onUserStopped(user.getUserIdentifier()); 385 } 386 } 387 onBootPhase(int phase)388 private void onBootPhase(int phase) { 389 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 390 migrateOldDataAfterSystemReady(); 391 deleteRepairModePersistentDataIfNeeded(); 392 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { 393 mHandler.post(() -> { 394 // In the case of an upgrade, PHASE_BOOT_COMPLETED means that a rollback to the old 395 // build can no longer occur. This is the time to destroy any migrated protectors. 396 destroyMigratedProtectors(); 397 398 loadEscrowData(); 399 }); 400 } 401 } 402 403 @VisibleForTesting 404 protected static class SynchronizedStrongAuthTracker 405 extends LockPatternUtils.StrongAuthTracker { SynchronizedStrongAuthTracker(Context context)406 public SynchronizedStrongAuthTracker(Context context) { 407 super(context); 408 } 409 410 @Override handleStrongAuthRequiredChanged(int strongAuthFlags, int userId)411 protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) { 412 synchronized (this) { 413 super.handleStrongAuthRequiredChanged(strongAuthFlags, userId); 414 } 415 } 416 417 @Override getStrongAuthForUser(int userId)418 public int getStrongAuthForUser(int userId) { 419 synchronized (this) { 420 return super.getStrongAuthForUser(userId); 421 } 422 } 423 register(LockSettingsStrongAuth strongAuth)424 void register(LockSettingsStrongAuth strongAuth) { 425 strongAuth.registerStrongAuthTracker(getStub()); 426 } 427 } 428 generateRandomProfilePassword()429 private LockscreenCredential generateRandomProfilePassword() { 430 byte[] randomLockSeed = SecureRandomUtils.randomBytes(40); 431 char[] newPasswordChars = HexEncoding.encode(randomLockSeed); 432 byte[] newPassword = new byte[newPasswordChars.length]; 433 for (int i = 0; i < newPasswordChars.length; i++) { 434 newPassword[i] = (byte) newPasswordChars[i]; 435 } 436 LockscreenCredential credential = 437 LockscreenCredential.createUnifiedProfilePassword(newPassword); 438 LockPatternUtils.zeroize(newPasswordChars); 439 LockPatternUtils.zeroize(newPassword); 440 LockPatternUtils.zeroize(randomLockSeed); 441 return credential; 442 } 443 444 /** 445 * Tie profile to primary profile if it is in unified mode and not tied before. 446 * Only for profiles which share credential with parent. (e.g. managed and clone profiles) 447 * 448 * @param profileUserId profile user Id 449 * @param profileUserPassword profile original password (when it has separated lock). 450 */ 451 @GuardedBy("mSpManager") tieProfileLockIfNecessary(int profileUserId, LockscreenCredential profileUserPassword)452 private void tieProfileLockIfNecessary(int profileUserId, 453 LockscreenCredential profileUserPassword) { 454 // Only for profiles that shares credential with parent 455 if (!isCredentialShareableWithParent(profileUserId)) { 456 return; 457 } 458 // Do not tie profile when separate challenge is enabled 459 if (getSeparateProfileChallengeEnabledInternal(profileUserId)) { 460 return; 461 } 462 // Do not tie profile to parent when it's done already 463 if (mStorage.hasChildProfileLock(profileUserId)) { 464 return; 465 } 466 final UserInfo parent = mUserManager.getProfileParent(profileUserId); 467 if (parent == null) { 468 return; 469 } 470 // If parent does not have a screen lock, simply clear credential from the profile, 471 // to maintain the invariant that unified profile should always have the same secure state 472 // as its parent. 473 if (!isUserSecure(parent.id) && !profileUserPassword.isNone()) { 474 Slogf.i(TAG, "Clearing password for profile user %d to match parent", profileUserId); 475 setLockCredentialInternal(LockscreenCredential.createNone(), profileUserPassword, 476 profileUserId, /* isLockTiedToParent= */ true); 477 return; 478 } 479 final long parentSid; 480 // Do not tie when the parent has no SID (but does have a screen lock). 481 // This can only happen during an upgrade path where SID is yet to be 482 // generated when the user unlocks for the first time. 483 try { 484 parentSid = getGateKeeperService().getSecureUserId(parent.id); 485 if (parentSid == 0) { 486 return; 487 } 488 } catch (RemoteException e) { 489 Slog.e(TAG, "Failed to talk to GateKeeper service", e); 490 return; 491 } 492 try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { 493 setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, 494 /* isLockTiedToParent= */ true); 495 tieProfileLockToParent(profileUserId, parent.id, unifiedProfilePassword); 496 mUnifiedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword, 497 parentSid); 498 } 499 } 500 501 static class Injector { 502 503 protected Context mContext; 504 private ServiceThread mHandlerThread; 505 private Handler mHandler; 506 Injector(Context context)507 public Injector(Context context) { 508 mContext = context; 509 } 510 getContext()511 public Context getContext() { 512 return mContext; 513 } 514 getServiceThread()515 public ServiceThread getServiceThread() { 516 if (mHandlerThread == null) { 517 mHandlerThread = new ServiceThread(TAG, 518 Process.THREAD_PRIORITY_BACKGROUND, 519 true /*allowIo*/); 520 mHandlerThread.start(); 521 } 522 return mHandlerThread; 523 } 524 getHandler(ServiceThread handlerThread)525 public Handler getHandler(ServiceThread handlerThread) { 526 if (mHandler == null) { 527 mHandler = new Handler(handlerThread.getLooper()); 528 } 529 return mHandler; 530 } 531 getStorage()532 public LockSettingsStorage getStorage() { 533 final LockSettingsStorage storage = new LockSettingsStorage(mContext); 534 storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { 535 @Override 536 public void initialize(SQLiteDatabase db) { 537 // Get the lockscreen default from a system property, if available 538 boolean lockScreenDisable = SystemProperties.getBoolean( 539 "ro.lockscreen.disable.default", false); 540 if (lockScreenDisable) { 541 storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); 542 } 543 } 544 }); 545 return storage; 546 } 547 getStrongAuth()548 public LockSettingsStrongAuth getStrongAuth() { 549 return new LockSettingsStrongAuth(mContext); 550 } 551 getStrongAuthTracker()552 public SynchronizedStrongAuthTracker getStrongAuthTracker() { 553 return new SynchronizedStrongAuthTracker(mContext); 554 } 555 getActivityManager()556 public IActivityManager getActivityManager() { 557 return ActivityManager.getService(); 558 } 559 getNotificationManager()560 public NotificationManager getNotificationManager() { 561 return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 562 } 563 getUserManager()564 public UserManager getUserManager() { 565 return (UserManager) mContext.getSystemService(Context.USER_SERVICE); 566 } 567 getUserManagerInternal()568 public UserManagerInternal getUserManagerInternal() { 569 return LocalServices.getService(UserManagerInternal.class); 570 } 571 572 /** 573 * Return the {@link DevicePolicyManager} object. 574 * 575 * Since LockSettingsService is considered a lower-level component than DevicePolicyManager, 576 * do NOT hold any lock in this class while calling into DevicePolicyManager to prevent 577 * the risk of deadlock. 578 */ getDevicePolicyManager()579 public DevicePolicyManager getDevicePolicyManager() { 580 return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 581 } 582 getDeviceStateCache()583 public DeviceStateCache getDeviceStateCache() { 584 return DeviceStateCache.getInstance(); 585 } 586 getRecoverableKeyStoreManager()587 public RecoverableKeyStoreManager getRecoverableKeyStoreManager() { 588 return RecoverableKeyStoreManager.getInstance(mContext); 589 } 590 getStorageManager()591 public IStorageManager getStorageManager() { 592 final IBinder service = ServiceManager.getService("mount"); 593 if (service != null) { 594 return IStorageManager.Stub.asInterface(service); 595 } 596 return null; 597 } 598 getStorageManagerInternal()599 public StorageManagerInternal getStorageManagerInternal() { 600 return LocalServices.getService(StorageManagerInternal.class); 601 } 602 getSyntheticPasswordManager(LockSettingsStorage storage)603 public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) { 604 return new SyntheticPasswordManager(getContext(), storage, getUserManager(), 605 new PasswordSlotManager()); 606 } 607 getRebootEscrowManager(RebootEscrowManager.Callbacks callbacks, LockSettingsStorage storage)608 public RebootEscrowManager getRebootEscrowManager(RebootEscrowManager.Callbacks callbacks, 609 LockSettingsStorage storage) { 610 return new RebootEscrowManager(mContext, callbacks, storage, 611 getHandler(getServiceThread()), getUserManagerInternal()); 612 } 613 binderGetCallingUid()614 public int binderGetCallingUid() { 615 return Binder.getCallingUid(); 616 } 617 isGsiRunning()618 public boolean isGsiRunning() { 619 return LockPatternUtils.isGsiRunning(); 620 } 621 getFingerprintManager()622 public FingerprintManager getFingerprintManager() { 623 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 624 return (FingerprintManager) mContext.getSystemService(Context.FINGERPRINT_SERVICE); 625 } else { 626 return null; 627 } 628 } 629 getFaceManager()630 public FaceManager getFaceManager() { 631 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { 632 return (FaceManager) mContext.getSystemService(Context.FACE_SERVICE); 633 } else { 634 return null; 635 } 636 } 637 getBiometricManager()638 public BiometricManager getBiometricManager() { 639 return (BiometricManager) mContext.getSystemService(Context.BIOMETRIC_SERVICE); 640 } 641 getKeyStore()642 public KeyStore getKeyStore() { 643 try { 644 KeyStore ks = KeyStore.getInstance( 645 SyntheticPasswordCrypto.androidKeystoreProviderName()); 646 ks.load(new AndroidKeyStoreLoadStoreParameter( 647 SyntheticPasswordCrypto.keyNamespace())); 648 return ks; 649 } catch (Exception e) { 650 throw new IllegalStateException("Cannot load keystore", e); 651 } 652 } 653 getKeyStoreAuthorization()654 public KeyStoreAuthorization getKeyStoreAuthorization() { 655 return KeyStoreAuthorization.getInstance(); 656 } 657 getUnifiedProfilePasswordCache(KeyStore ks)658 public @NonNull UnifiedProfilePasswordCache getUnifiedProfilePasswordCache(KeyStore ks) { 659 return new UnifiedProfilePasswordCache(ks); 660 } 661 isHeadlessSystemUserMode()662 public boolean isHeadlessSystemUserMode() { 663 return UserManager.isHeadlessSystemUserMode(); 664 } 665 isMainUserPermanentAdmin()666 public boolean isMainUserPermanentAdmin() { 667 return Resources.getSystem() 668 .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin); 669 } 670 } 671 LockSettingsService(Context context)672 public LockSettingsService(Context context) { 673 this(new Injector(context)); 674 } 675 676 @VisibleForTesting LockSettingsService(Injector injector)677 protected LockSettingsService(Injector injector) { 678 mInjector = injector; 679 mContext = injector.getContext(); 680 mKeyStore = injector.getKeyStore(); 681 mKeyStoreAuthorization = injector.getKeyStoreAuthorization(); 682 mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(); 683 mHandler = injector.getHandler(injector.getServiceThread()); 684 mStrongAuth = injector.getStrongAuth(); 685 mActivityManager = injector.getActivityManager(); 686 687 IntentFilter filter = new IntentFilter(); 688 filter.addAction(Intent.ACTION_USER_STARTING); 689 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 690 injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, 691 null, null); 692 693 mStorage = injector.getStorage(); 694 mNotificationManager = injector.getNotificationManager(); 695 mUserManager = injector.getUserManager(); 696 mStorageManager = injector.getStorageManager(); 697 mStorageManagerInternal = injector.getStorageManagerInternal(); 698 mStrongAuthTracker = injector.getStrongAuthTracker(); 699 mStrongAuthTracker.register(mStrongAuth); 700 mGatekeeperPasswords = new LongSparseArray<>(); 701 702 mSpManager = injector.getSyntheticPasswordManager(mStorage); 703 mUnifiedProfilePasswordCache = injector.getUnifiedProfilePasswordCache(mKeyStore); 704 mBiometricDeferredQueue = new BiometricDeferredQueue(mSpManager); 705 706 mRebootEscrowManager = injector.getRebootEscrowManager(new RebootEscrowCallbacks(), 707 mStorage); 708 709 LocalServices.addService(LockSettingsInternal.class, new LocalService()); 710 } 711 updateActivatedEncryptionNotifications(String reason)712 private void updateActivatedEncryptionNotifications(String reason) { 713 for (UserInfo userInfo : mUserManager.getUsers()) { 714 Context userContext = mContext.createContextAsUser(UserHandle.of(userInfo.id), 0); 715 NotificationManager nm = (NotificationManager) 716 userContext.getSystemService(Context.NOTIFICATION_SERVICE); 717 for (StatusBarNotification notification : nm.getActiveNotifications()) { 718 if (notification.getId() == SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION) { 719 maybeShowEncryptionNotificationForUser(userInfo.id, reason); 720 break; 721 } 722 } 723 } 724 } 725 726 /** 727 * If the user is a managed profile whose credential-encrypted storage is locked, show a 728 * notification requesting the user to unlock the device. 729 */ maybeShowEncryptionNotificationForUser(@serIdInt int userId, String reason)730 private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId, String reason) { 731 final UserInfo user = mUserManager.getUserInfo(userId); 732 if (!user.isManagedProfile()) { 733 // When the user is locked, we communicate it loud-and-clear 734 // on the lockscreen; we only show a notification below for 735 // locked managed profiles. 736 return; 737 } 738 739 if (isCeStorageUnlocked(userId)) { 740 // If the user's CE storage is already unlocked, then the user will be automatically 741 // unlocked, so there is no need to show the notification. 742 return; 743 } 744 745 final UserHandle userHandle = user.getUserHandle(); 746 final boolean isSecure = isUserSecure(userId); 747 if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) { 748 UserInfo parent = mUserManager.getProfileParent(userId); 749 if (parent != null && 750 mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) && 751 !mUserManager.isQuietModeEnabled(userHandle)) { 752 // Only show notifications for managed profiles once their parent 753 // user is unlocked. 754 showEncryptionNotificationForProfile(userHandle, parent.getUserHandle(), reason); 755 } 756 } 757 } 758 showEncryptionNotificationForProfile(UserHandle user, UserHandle parent, String reason)759 private void showEncryptionNotificationForProfile(UserHandle user, UserHandle parent, 760 String reason) { 761 CharSequence title = getEncryptionNotificationTitle(); 762 CharSequence message = getEncryptionNotificationMessage(); 763 CharSequence detail = getEncryptionNotificationDetail(); 764 765 final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE); 766 final Intent unlockIntent = 767 km.createConfirmDeviceCredentialIntent(null, null, user.getIdentifier()); 768 if (unlockIntent == null) { 769 return; 770 } 771 772 // Suppress all notifications on non-FBE devices for now 773 if (!StorageManager.isFileEncrypted()) return; 774 775 unlockIntent.setFlags( 776 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 777 PendingIntent intent = PendingIntent.getActivityAsUser(mContext, 0, unlockIntent, 778 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED, 779 null, parent); 780 781 Slogf.d(TAG, "Showing encryption notification for user %d; reason: %s", 782 user.getIdentifier(), reason); 783 784 showEncryptionNotification(user, title, message, detail, intent); 785 } 786 getEncryptionNotificationTitle()787 private String getEncryptionNotificationTitle() { 788 return mInjector.getDevicePolicyManager().getResources().getString( 789 PROFILE_ENCRYPTED_TITLE, 790 () -> mContext.getString(R.string.profile_encrypted_title)); 791 } 792 getEncryptionNotificationDetail()793 private String getEncryptionNotificationDetail() { 794 return mInjector.getDevicePolicyManager().getResources().getString( 795 PROFILE_ENCRYPTED_DETAIL, 796 () -> mContext.getString(R.string.profile_encrypted_detail)); 797 } 798 getEncryptionNotificationMessage()799 private String getEncryptionNotificationMessage() { 800 return mInjector.getDevicePolicyManager().getResources().getString( 801 PROFILE_ENCRYPTED_MESSAGE, 802 () -> mContext.getString(R.string.profile_encrypted_message)); 803 } 804 showEncryptionNotification(UserHandle user, CharSequence title, CharSequence message, CharSequence detail, PendingIntent intent)805 private void showEncryptionNotification(UserHandle user, CharSequence title, 806 CharSequence message, CharSequence detail, PendingIntent intent) { 807 Notification notification = 808 new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) 809 .setSmallIcon(com.android.internal.R.drawable.ic_user_secure) 810 .setWhen(0) 811 .setOngoing(true) 812 .setTicker(title) 813 .setColor(mContext.getColor( 814 com.android.internal.R.color.system_notification_accent_color)) 815 .setContentTitle(title) 816 .setContentText(message) 817 .setSubText(detail) 818 .setVisibility(Notification.VISIBILITY_PUBLIC) 819 .setContentIntent(intent) 820 .build(); 821 mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION, 822 notification, user); 823 } 824 hideEncryptionNotification(UserHandle userHandle)825 private void hideEncryptionNotification(UserHandle userHandle) { 826 Slogf.d(TAG, "Hiding encryption notification for user %d", userHandle.getIdentifier()); 827 mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION, 828 userHandle); 829 } 830 831 @VisibleForTesting 832 @RequiresPermission(anyOf = { 833 android.Manifest.permission.MANAGE_USERS, 834 android.Manifest.permission.QUERY_USERS, 835 android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true) onUserStopped(int userId)836 void onUserStopped(int userId) { 837 hideEncryptionNotification(new UserHandle(userId)); 838 839 // Normally, CE storage is locked when a user is stopped, and restarting the user requires 840 // strong auth. Therefore, reset the user's strong auth flags. The exception is users that 841 // allow delayed locking; under some circumstances, biometric authentication is allowed to 842 // restart such users. Don't reset the strong auth flags for such users. 843 // 844 // TODO(b/319142556): It might make more sense to reset the strong auth flags when CE 845 // storage is locked, instead of when the user is stopped. This would ensure the flags get 846 // reset if CE storage is locked later for a user that allows delayed locking. 847 if (android.os.Flags.allowPrivateProfile() 848 && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace() 849 && android.multiuser.Flags.enablePrivateSpaceFeatures()) { 850 UserProperties userProperties = getUserProperties(userId); 851 if (userProperties != null && userProperties.getAllowStoppingUserWithDelayedLocking()) { 852 return; 853 } 854 } 855 int strongAuthRequired = LockPatternUtils.StrongAuthTracker.getDefaultFlags(mContext); 856 requireStrongAuth(strongAuthRequired, userId); 857 858 // Don't keep the password metrics in memory for a stopped user that will require strong 859 // auth to start again, since strong auth will make the password metrics available again. 860 synchronized (this) { 861 mUserPasswordMetrics.remove(userId); 862 } 863 } 864 onUserStarting(final int userId)865 private void onUserStarting(final int userId) { 866 maybeShowEncryptionNotificationForUser(userId, "user started"); 867 } 868 869 /** 870 * Removes the LSS state for the given userId if the userId was reused without its LSS state 871 * being fully removed. 872 * <p> 873 * This is primarily needed for users that were removed by Android 13 or earlier, which didn't 874 * guarantee removal of LSS state as it relied on the {@code ACTION_USER_REMOVED} intent. It is 875 * also needed because {@link #removeUser()} delays requests to remove LSS state until Weaver is 876 * guaranteed to be available, so they can be lost. 877 * <p> 878 * Stale state is detected by checking whether the user serial number changed. This works 879 * because user serial numbers are never reused. 880 */ removeStateForReusedUserIdIfNecessary(@serIdInt int userId, int serialNumber)881 private void removeStateForReusedUserIdIfNecessary(@UserIdInt int userId, int serialNumber) { 882 if (userId == UserHandle.USER_SYSTEM) { 883 // Short circuit as we never clean up user 0. 884 return; 885 } 886 int storedSerialNumber = mStorage.getInt(USER_SERIAL_NUMBER_KEY, -1, userId); 887 if (storedSerialNumber != serialNumber) { 888 // If LockSettingsStorage does not have a copy of the serial number, it could be either 889 // this is a user created before the serial number recording logic is introduced, or 890 // the user does not exist or was removed and cleaned up properly. In either case, don't 891 // invoke removeUserState(). 892 if (storedSerialNumber != -1) { 893 Slogf.i(TAG, "Removing stale state for reused userId %d (serial %d => %d)", userId, 894 storedSerialNumber, serialNumber); 895 removeUserState(userId); 896 } 897 mStorage.setInt(USER_SERIAL_NUMBER_KEY, serialNumber, userId); 898 } 899 } 900 onUserUnlocking(final int userId)901 private void onUserUnlocking(final int userId) { 902 // Perform tasks which require locks in LSS on a handler, as we are callbacks from 903 // ActivityManager.unlockUser() 904 mHandler.post(new Runnable() { 905 @Override 906 public void run() { 907 // Hide notification first, as tie profile lock takes time 908 hideEncryptionNotification(new UserHandle(userId)); 909 910 synchronized (mSpManager) { 911 tieProfileLockIfNecessary(userId, LockscreenCredential.createNone()); 912 } 913 } 914 }); 915 } 916 917 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 918 @Override 919 public void onReceive(Context context, Intent intent) { 920 if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) { 921 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 922 mStorage.prefetchUser(userHandle); 923 } else if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) { 924 updateActivatedEncryptionNotifications("locale changed"); 925 } 926 } 927 }; 928 929 @Override // binder interface systemReady()930 public void systemReady() { 931 checkWritePermission(); 932 933 mHasSecureLockScreen = mContext.getPackageManager() 934 .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN); 935 migrateOldData(); 936 getAuthSecretHal(); 937 mDeviceProvisionedObserver.onSystemReady(); 938 939 // Work around an issue in PropertyInvalidatedCache where the cache doesn't work until the 940 // first invalidation. This can be removed if PropertyInvalidatedCache is fixed. 941 LockPatternUtils.invalidateCredentialTypeCache(); 942 943 // TODO: maybe skip this for split system user mode. 944 mStorage.prefetchUser(UserHandle.USER_SYSTEM); 945 mBiometricDeferredQueue.systemReady(mInjector.getFingerprintManager(), 946 mInjector.getFaceManager(), mInjector.getBiometricManager()); 947 if (android.os.Flags.allowPrivateProfile() 948 && android.multiuser.Flags.enablePrivateSpaceFeatures() 949 && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) { 950 mStorageManagerInternal.registerStorageLockEventListener(mCeStorageLockEventListener); 951 } 952 } 953 954 private final ICeStorageLockEventListener mCeStorageLockEventListener = 955 new ICeStorageLockEventListener() { 956 @Override 957 public void onStorageLocked(int userId) { 958 Slog.i(TAG, "Storage lock event received for " + userId); 959 if (android.os.Flags.allowPrivateProfile() 960 && android.multiuser.Flags.enablePrivateSpaceFeatures() 961 && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) { 962 mHandler.post(() -> { 963 UserProperties userProperties = getUserProperties(userId); 964 if (userProperties != null && userProperties 965 .getAllowStoppingUserWithDelayedLocking()) { 966 int strongAuthRequired = LockPatternUtils.StrongAuthTracker 967 .getDefaultFlags(mContext); 968 requireStrongAuth(strongAuthRequired, userId); 969 } 970 }); 971 } 972 }}; 973 loadEscrowData()974 private void loadEscrowData() { 975 mRebootEscrowManager.loadRebootEscrowDataIfAvailable(mHandler); 976 } 977 getAuthSecretHal()978 private void getAuthSecretHal() { 979 mAuthSecretService = 980 IAuthSecret.Stub.asInterface( 981 ServiceManager.waitForDeclaredService(IAuthSecret.DESCRIPTOR + "/default")); 982 if (mAuthSecretService != null) { 983 Slog.i(TAG, "Device implements AIDL AuthSecret HAL"); 984 } else { 985 try { 986 android.hardware.authsecret.V1_0.IAuthSecret authSecretServiceHidl = 987 android.hardware.authsecret.V1_0.IAuthSecret.getService(/* retry */ true); 988 mAuthSecretService = new AuthSecretHidlAdapter(authSecretServiceHidl); 989 Slog.i(TAG, "Device implements HIDL AuthSecret HAL"); 990 } catch (NoSuchElementException e) { 991 Slog.i(TAG, "Device doesn't implement AuthSecret HAL"); 992 } catch (RemoteException e) { 993 Slog.w(TAG, "Failed to get AuthSecret HAL(hidl)", e); 994 } 995 } 996 } 997 migrateOldData()998 private void migrateOldData() { 999 if (getString(MIGRATED_KEYSTORE_NS, null, 0) == null) { 1000 boolean success = true; 1001 synchronized (mSpManager) { 1002 success &= mSpManager.migrateKeyNamespace(); 1003 } 1004 success &= migrateProfileLockKeys(); 1005 if (success) { 1006 setString(MIGRATED_KEYSTORE_NS, "true", 0); 1007 Slog.i(TAG, "Migrated keys to LSS namespace"); 1008 } else { 1009 Slog.w(TAG, "Failed to migrate keys to LSS namespace"); 1010 } 1011 } 1012 1013 } 1014 1015 @VisibleForTesting migrateOldDataAfterSystemReady()1016 void migrateOldDataAfterSystemReady() { 1017 // Write the FRP persistent data block if needed. 1018 // 1019 // The original purpose of this code was to write the FRP block for the first time, when 1020 // upgrading from Android 8.1 or earlier which didn't use the FRP block. This code has 1021 // since been repurposed to also fix the "bad" (non-forwards-compatible) FRP block written 1022 // by Android 14 Beta 2. For this reason, the database key used here has been renamed from 1023 // "migrated_frp" to "migrated_frp2" to cause migrateFrpCredential() to run again on devices 1024 // where it had run before. 1025 if (LockPatternUtils.frpCredentialEnabled(mContext) 1026 && !getBoolean(MIGRATED_FRP2, false, 0)) { 1027 migrateFrpCredential(); 1028 setBoolean(MIGRATED_FRP2, true, 0); 1029 } 1030 } 1031 1032 /** 1033 * Write the FRP persistent data block if the following are satisfied: 1034 * - the user who owns the FRP credential has a nonempty credential 1035 * - the FRP persistent data block doesn't exist or uses the "bad" format from Android 14 Beta 2 1036 */ migrateFrpCredential()1037 private void migrateFrpCredential() { 1038 PersistentData data = mStorage.readPersistentDataBlock(); 1039 if (data != PersistentData.NONE && !data.isBadFormatFromAndroid14Beta()) { 1040 return; 1041 } 1042 for (UserInfo userInfo : mUserManager.getUsers()) { 1043 if (userOwnsFrpCredential(mContext, userInfo) && isUserSecure(userInfo.id)) { 1044 synchronized (mSpManager) { 1045 int actualQuality = (int) getLong(LockPatternUtils.PASSWORD_TYPE_KEY, 1046 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id); 1047 1048 mSpManager.migrateFrpPasswordLocked( 1049 getCurrentLskfBasedProtectorId(userInfo.id), 1050 userInfo, 1051 redactActualQualityToMostLenientEquivalentQuality(actualQuality)); 1052 } 1053 return; 1054 } 1055 } 1056 } 1057 migrateProfileLockKeys()1058 private boolean migrateProfileLockKeys() { 1059 boolean success = true; 1060 final List<UserInfo> users = mUserManager.getUsers(); 1061 final int userCount = users.size(); 1062 for (int i = 0; i < userCount; i++) { 1063 UserInfo user = users.get(i); 1064 if (isCredentialShareableWithParent(user.id) 1065 && !getSeparateProfileChallengeEnabledInternal(user.id)) { 1066 success &= SyntheticPasswordCrypto.migrateLockSettingsKey( 1067 PROFILE_KEY_NAME_ENCRYPT + user.id); 1068 success &= SyntheticPasswordCrypto.migrateLockSettingsKey( 1069 PROFILE_KEY_NAME_DECRYPT + user.id); 1070 } 1071 } 1072 return success; 1073 } 1074 1075 @VisibleForTesting deleteRepairModePersistentDataIfNeeded()1076 void deleteRepairModePersistentDataIfNeeded() { 1077 if (!LockPatternUtils.isRepairModeSupported(mContext) 1078 || LockPatternUtils.isRepairModeActive(mContext) 1079 || mInjector.isGsiRunning()) { 1080 return; 1081 } 1082 mStorage.deleteRepairModePersistentData(); 1083 } 1084 isWeaverDisabledOnUnsecuredUsers()1085 private boolean isWeaverDisabledOnUnsecuredUsers() { 1086 return mContext.getResources().getBoolean( 1087 com.android.internal.R.bool.config_disableWeaverOnUnsecuredUsers); 1088 } 1089 1090 // This is called when Weaver is guaranteed to be available (if the device supports Weaver). 1091 // It does any synthetic password related work that was delayed from earlier in the boot. onThirdPartyAppsStarted()1092 private void onThirdPartyAppsStarted() { 1093 synchronized (mUserCreationAndRemovalLock) { 1094 // Handle delayed calls to LSS.removeUser() and LSS.createNewUser(). 1095 for (int i = 0; i < mEarlyRemovedUsers.size(); i++) { 1096 int userId = mEarlyRemovedUsers.keyAt(i); 1097 Slogf.i(TAG, "Removing locksettings state for removed user %d now that boot " 1098 + "is complete", userId); 1099 removeUserState(userId); 1100 } 1101 mEarlyRemovedUsers = null; // no longer needed 1102 for (int i = 0; i < mEarlyCreatedUsers.size(); i++) { 1103 int userId = mEarlyCreatedUsers.keyAt(i); 1104 int serialNumber = mEarlyCreatedUsers.valueAt(i); 1105 1106 removeStateForReusedUserIdIfNecessary(userId, serialNumber); 1107 Slogf.i(TAG, "Creating locksettings state for user %d now that boot is complete", 1108 userId); 1109 initializeSyntheticPassword(userId); 1110 } 1111 mEarlyCreatedUsers = null; // no longer needed 1112 1113 // Do a one-time migration for any unsecured users: create the user's synthetic password 1114 // if not already done, encrypt the user's CE key with the synthetic password if not 1115 // already done, and create the user's Keystore super keys if not already done. 1116 // 1117 // This is needed for the following cases: 1118 // 1119 // - Finalizing the creation of the system user on the first boot of a device, as the 1120 // system user is special and doesn't go through the normal user creation flow. 1121 // 1122 // - Upgrading from Android 13 or earlier, where unsecured users didn't necessarily have 1123 // a synthetic password, and if they did have a synthetic password their CE key wasn't 1124 // encrypted by it. Also, unsecured users didn't have Keystore super keys. 1125 // 1126 // - Upgrading from Android 14, where unsecured users didn't have Keystore super keys. 1127 // 1128 // - Upgrading from a build with config_disableWeaverOnUnsecuredUsers=false to one with 1129 // config_disableWeaverOnUnsecuredUsers=true. (We don't bother to proactively add 1130 // Weaver for the reverse update to false, as it's too late to help in that case.) 1131 // 1132 // The end result is that all users, regardless of whether they are secured or not, have 1133 // a synthetic password with all keys initialized and protected by it, and honoring 1134 // config_disableWeaverOnUnsecuredUsers=true when applicable. 1135 // 1136 // Note: if this migration gets interrupted (e.g. by the device powering off), there 1137 // shouldn't be a problem since this will run again on the next boot, and 1138 // setCeStorageProtection() and initKeystoreSuperKeys(..., true) are idempotent. 1139 if (!getBoolean(MIGRATED_SP_FULL, false, 0) 1140 || (isWeaverDisabledOnUnsecuredUsers() 1141 && !getBoolean(MIGRATED_WEAVER_DISABLED_ON_UNSECURED_USERS, false, 0))) { 1142 for (UserInfo user : mUserManager.getAliveUsers()) { 1143 removeStateForReusedUserIdIfNecessary(user.id, user.serialNumber); 1144 synchronized (mSpManager) { 1145 migrateUserToSpWithBoundKeysLocked(user.id); 1146 } 1147 } 1148 setBoolean(MIGRATED_SP_FULL, true, 0); 1149 if (isWeaverDisabledOnUnsecuredUsers()) { 1150 setBoolean(MIGRATED_WEAVER_DISABLED_ON_UNSECURED_USERS, true, 0); 1151 } 1152 } 1153 1154 mThirdPartyAppsStarted = true; 1155 } 1156 } 1157 1158 @GuardedBy("mSpManager") migrateUserToSpWithBoundKeysLocked(@serIdInt int userId)1159 private void migrateUserToSpWithBoundKeysLocked(@UserIdInt int userId) { 1160 if (isUserSecure(userId)) { 1161 Slogf.d(TAG, "User %d is secured; no migration needed", userId); 1162 return; 1163 } 1164 long protectorId = getCurrentLskfBasedProtectorId(userId); 1165 if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) { 1166 Slogf.i(TAG, "Migrating unsecured user %d to SP-based credential", userId); 1167 initializeSyntheticPassword(userId); 1168 return; 1169 } 1170 Slogf.i(TAG, "Existing unsecured user %d has a synthetic password", userId); 1171 AuthenticationResult result = mSpManager.unlockLskfBasedProtector( 1172 getGateKeeperService(), protectorId, LockscreenCredential.createNone(), userId, 1173 null); 1174 SyntheticPassword sp = result.syntheticPassword; 1175 if (isWeaverDisabledOnUnsecuredUsers()) { 1176 Slog.i(TAG, "config_disableWeaverOnUnsecuredUsers=true"); 1177 1178 // If config_disableWeaverOnUnsecuredUsers=true, then the Weaver HAL may be buggy and 1179 // need multiple retries before it works here to unwrap the SP, if the SP was already 1180 // protected by Weaver. 1181 for (int i = 0; i < 12 && sp == null; i++) { 1182 Slog.e(TAG, "Failed to unwrap synthetic password. Waiting 5 seconds to retry."); 1183 SystemClock.sleep(5000); 1184 result = mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId, 1185 LockscreenCredential.createNone(), userId, null); 1186 sp = result.syntheticPassword; 1187 } 1188 if (sp == null) { 1189 throw new IllegalStateException( 1190 "Failed to unwrap synthetic password for unsecured user"); 1191 } 1192 // If the SP is protected by Weaver, then remove the Weaver protection in order to make 1193 // config_disableWeaverOnUnsecuredUsers=true take effect. 1194 if (result.usedWeaver) { 1195 Slog.i(TAG, "Removing Weaver protection from the synthetic password"); 1196 // Create a new protector, which will not use Weaver. 1197 long newProtectorId = mSpManager.createLskfBasedProtector( 1198 getGateKeeperService(), LockscreenCredential.createNone(), sp, userId); 1199 1200 // Out of paranoia, make sure the new protector really works. 1201 result = mSpManager.unlockLskfBasedProtector(getGateKeeperService(), 1202 newProtectorId, LockscreenCredential.createNone(), userId, null); 1203 sp = result.syntheticPassword; 1204 if (sp == null) { 1205 throw new IllegalStateException("New SP protector does not work"); 1206 } 1207 1208 // Replace the protector. Wait until PHASE_BOOT_COMPLETED to destroy the old 1209 // protector, since the Weaver slot erasure and freeing cannot be rolled back. 1210 setCurrentLskfBasedProtectorId(newProtectorId, userId); 1211 mProtectorsToDestroyOnBootCompleted.add(new Pair(protectorId, userId)); 1212 } else { 1213 Slog.i(TAG, "Synthetic password is already not protected by Weaver"); 1214 } 1215 } else if (sp == null) { 1216 throw new IllegalStateException( 1217 "Failed to unwrap synthetic password for unsecured user " + userId); 1218 } 1219 1220 // Call setCeStorageProtection(), to re-encrypt the CE key with the SP if it's currently 1221 // encrypted by an empty secret. If the CE key is already encrypted by the SP, then this is 1222 // a no-op except for some log messages. 1223 Slogf.i(TAG, "Encrypting CE key of user %d with synthetic password", userId); 1224 setCeStorageProtection(userId, sp); 1225 1226 Slogf.i(TAG, "Initializing Keystore super keys for user %d", userId); 1227 initKeystoreSuperKeys(userId, sp, /* allowExisting= */ true); 1228 } 1229 destroyMigratedProtectors()1230 private void destroyMigratedProtectors() { 1231 if (!mProtectorsToDestroyOnBootCompleted.isEmpty()) { 1232 synchronized (mSpManager) { 1233 for (Pair<Long, Integer> pair : mProtectorsToDestroyOnBootCompleted) { 1234 mSpManager.destroyLskfBasedProtector(pair.first, pair.second); 1235 } 1236 } 1237 } 1238 mProtectorsToDestroyOnBootCompleted = null; // The list is no longer needed. 1239 } 1240 1241 /** 1242 * Returns the lowest password quality that still presents the same UI for entering it. 1243 * 1244 * For the FRP credential, we do not want to leak the actual quality of the password, only what 1245 * kind of UI it requires. However, when migrating, we only know the actual quality, not the 1246 * originally requested quality; since this is only used to determine what input variant to 1247 * present to the user, we just assume the lowest possible quality was requested. 1248 */ redactActualQualityToMostLenientEquivalentQuality(int quality)1249 private int redactActualQualityToMostLenientEquivalentQuality(int quality) { 1250 switch (quality) { 1251 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 1252 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 1253 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 1254 return DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; 1255 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 1256 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 1257 return DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 1258 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 1259 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 1260 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: 1261 case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK: 1262 default: 1263 return quality; 1264 } 1265 } 1266 enforceFrpNotActive()1267 private void enforceFrpNotActive() { 1268 final int mainUserId = mInjector.getUserManagerInternal().getMainUserId(); 1269 if (mainUserId < 0) { 1270 Slog.d(TAG, "No Main user on device; skipping enforceFrpNotActive"); 1271 return; 1272 } 1273 1274 final ContentResolver cr = mContext.getContentResolver(); 1275 final boolean inSetupWizard = Settings.Secure.getIntForUser(cr, 1276 Settings.Secure.USER_SETUP_COMPLETE, 0, mainUserId) == 0; 1277 final boolean isFrpActive = android.security.Flags.frpEnforcement() 1278 ? mStorage.isFactoryResetProtectionActive() 1279 : (Settings.Global.getInt(cr, Settings.Global.SECURE_FRP_MODE, 0) == 1) 1280 && inSetupWizard; 1281 1282 if (isFrpActive) { 1283 throw new SecurityException("Cannot change credential while factory reset protection" 1284 + " is active"); 1285 } 1286 } 1287 checkWritePermission()1288 private final void checkWritePermission() { 1289 mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite"); 1290 } 1291 checkPasswordReadPermission()1292 private final void checkPasswordReadPermission() { 1293 mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead"); 1294 } 1295 checkPasswordHavePermission()1296 private final void checkPasswordHavePermission() { 1297 mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsHave"); 1298 } 1299 checkDatabaseReadPermission(String requestedKey, int userId)1300 private final void checkDatabaseReadPermission(String requestedKey, int userId) { 1301 if (!hasPermission(PERMISSION)) { 1302 throw new SecurityException("uid=" + getCallingUid() + " needs permission " 1303 + PERMISSION + " to read " + requestedKey + " for user " + userId); 1304 } 1305 } 1306 checkBiometricPermission()1307 private final void checkBiometricPermission() { 1308 mContext.enforceCallingOrSelfPermission(BIOMETRIC_PERMISSION, "LockSettingsBiometric"); 1309 } 1310 hasPermission(String permission)1311 private boolean hasPermission(String permission) { 1312 return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; 1313 } 1314 checkManageWeakEscrowTokenMethodUsage()1315 private void checkManageWeakEscrowTokenMethodUsage() { 1316 mContext.enforceCallingOrSelfPermission( 1317 Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN, 1318 "Requires MANAGE_WEAK_ESCROW_TOKEN permission."); 1319 if (!RoSystemFeatures.hasFeatureAutomotive(mContext)) { 1320 throw new IllegalArgumentException( 1321 "Weak escrow token are only for automotive devices."); 1322 } 1323 } 1324 1325 @Override hasSecureLockScreen()1326 public boolean hasSecureLockScreen() { 1327 return mHasSecureLockScreen; 1328 } 1329 1330 @Override getSeparateProfileChallengeEnabled(int userId)1331 public boolean getSeparateProfileChallengeEnabled(int userId) { 1332 checkDatabaseReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId); 1333 return getSeparateProfileChallengeEnabledInternal(userId); 1334 } 1335 getSeparateProfileChallengeEnabledInternal(int userId)1336 private boolean getSeparateProfileChallengeEnabledInternal(int userId) { 1337 synchronized (mSeparateChallengeLock) { 1338 return mStorage.getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId); 1339 } 1340 } 1341 1342 @Override setSeparateProfileChallengeEnabled(int userId, boolean enabled, LockscreenCredential profileUserPassword)1343 public void setSeparateProfileChallengeEnabled(int userId, boolean enabled, 1344 LockscreenCredential profileUserPassword) { 1345 checkWritePermission(); 1346 if (!mHasSecureLockScreen 1347 && profileUserPassword != null 1348 && profileUserPassword.getType() != CREDENTIAL_TYPE_NONE) { 1349 throw new UnsupportedOperationException( 1350 "This operation requires secure lock screen feature."); 1351 } 1352 synchronized (mSeparateChallengeLock) { 1353 setSeparateProfileChallengeEnabledLocked(userId, enabled, profileUserPassword != null 1354 ? profileUserPassword : LockscreenCredential.createNone()); 1355 } 1356 notifySeparateProfileChallengeChanged(userId); 1357 } 1358 1359 @GuardedBy("mSeparateChallengeLock") setSeparateProfileChallengeEnabledLocked(@serIdInt int userId, boolean enabled, LockscreenCredential profileUserPassword)1360 private void setSeparateProfileChallengeEnabledLocked(@UserIdInt int userId, 1361 boolean enabled, LockscreenCredential profileUserPassword) { 1362 final boolean old = getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId); 1363 setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId); 1364 try { 1365 if (enabled) { 1366 mStorage.removeChildProfileLock(userId); 1367 removeKeystoreProfileKey(userId); 1368 } else { 1369 synchronized (mSpManager) { 1370 tieProfileLockIfNecessary(userId, profileUserPassword); 1371 } 1372 } 1373 } catch (IllegalStateException e) { 1374 setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, old, userId); 1375 throw e; 1376 } 1377 } 1378 notifySeparateProfileChallengeChanged(int userId)1379 private void notifySeparateProfileChallengeChanged(int userId) { 1380 // LSS cannot call into DPM directly, otherwise it will cause deadlock. 1381 // In this case, calling DPM on a handler thread is OK since DPM doesn't 1382 // expect reportSeparateProfileChallengeChanged() to happen synchronously. 1383 mHandler.post(() -> { 1384 final DevicePolicyManagerInternal dpmi = LocalServices.getService( 1385 DevicePolicyManagerInternal.class); 1386 if (dpmi != null) { 1387 dpmi.reportSeparateProfileChallengeChanged(userId); 1388 } 1389 }); 1390 } 1391 1392 @Override setBoolean(String key, boolean value, int userId)1393 public void setBoolean(String key, boolean value, int userId) { 1394 checkWritePermission(); 1395 Objects.requireNonNull(key); 1396 mStorage.setBoolean(key, value, userId); 1397 } 1398 1399 @Override setLong(String key, long value, int userId)1400 public void setLong(String key, long value, int userId) { 1401 checkWritePermission(); 1402 Objects.requireNonNull(key); 1403 mStorage.setLong(key, value, userId); 1404 } 1405 1406 @Override setString(String key, String value, int userId)1407 public void setString(String key, String value, int userId) { 1408 checkWritePermission(); 1409 Objects.requireNonNull(key); 1410 mStorage.setString(key, value, userId); 1411 } 1412 1413 @Override getBoolean(String key, boolean defaultValue, int userId)1414 public boolean getBoolean(String key, boolean defaultValue, int userId) { 1415 checkDatabaseReadPermission(key, userId); 1416 return mStorage.getBoolean(key, defaultValue, userId); 1417 } 1418 1419 @Override getLong(String key, long defaultValue, int userId)1420 public long getLong(String key, long defaultValue, int userId) { 1421 checkDatabaseReadPermission(key, userId); 1422 return mStorage.getLong(key, defaultValue, userId); 1423 } 1424 1425 @Override getString(String key, String defaultValue, int userId)1426 public String getString(String key, String defaultValue, int userId) { 1427 checkDatabaseReadPermission(key, userId); 1428 return mStorage.getString(key, defaultValue, userId); 1429 } 1430 1431 // Not relevant for new devices, but some legacy devices still have PASSWORD_TYPE_KEY around to 1432 // distinguish between credential types. getKeyguardStoredQuality(int userId)1433 private int getKeyguardStoredQuality(int userId) { 1434 return (int) mStorage.getLong(LockPatternUtils.PASSWORD_TYPE_KEY, 1435 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId); 1436 } 1437 1438 /* 1439 * Gets the PIN length for the given user if it is currently available. 1440 * Can only be invoked by process/activity that have the right permission. 1441 * Returns: 1442 * A. Actual PIN length if credential type PIN and auto confirm feature is enabled 1443 * for the user or user's PIN has been successfully verified since the device booted 1444 * B. PIN_LENGTH_UNAVAILABLE if pin length is not stored/available 1445 */ 1446 @Override getPinLength(int userId)1447 public int getPinLength(int userId) { 1448 checkPasswordHavePermission(); 1449 PasswordMetrics passwordMetrics = getUserPasswordMetrics(userId); 1450 if (passwordMetrics != null && passwordMetrics.credType == CREDENTIAL_TYPE_PIN) { 1451 return passwordMetrics.length; 1452 } 1453 synchronized (mSpManager) { 1454 final long protectorId = getCurrentLskfBasedProtectorId(userId); 1455 if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) { 1456 // Only possible for new users during early boot (before onThirdPartyAppsStarted()) 1457 return PIN_LENGTH_UNAVAILABLE; 1458 } 1459 return mSpManager.getPinLength(protectorId, userId); 1460 } 1461 } 1462 1463 /** 1464 * {@link LockPatternUtils#refreshStoredPinLength(int)} 1465 * @param userId user id of the user whose pin length we want to save 1466 * @return true/false depending on whether PIN length has been saved or not 1467 */ 1468 @Override refreshStoredPinLength(int userId)1469 public boolean refreshStoredPinLength(int userId) { 1470 checkPasswordHavePermission(); 1471 synchronized (mSpManager) { 1472 PasswordMetrics passwordMetrics = getUserPasswordMetrics(userId); 1473 if (passwordMetrics != null) { 1474 final long protectorId = getCurrentLskfBasedProtectorId(userId); 1475 return mSpManager.refreshPinLengthOnDisk(passwordMetrics, protectorId, userId); 1476 } else { 1477 Log.w(TAG, "PasswordMetrics is not available"); 1478 return false; 1479 } 1480 } 1481 } 1482 1483 /** 1484 * This API is cached; whenever the result would change, 1485 * {@link com.android.internal.widget.LockPatternUtils#invalidateCredentialTypeCache} 1486 * must be called. 1487 */ 1488 @Override getCredentialType(int userId)1489 public int getCredentialType(int userId) { 1490 checkPasswordHavePermission(); 1491 return getCredentialTypeInternal(userId); 1492 } 1493 1494 /** 1495 * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, 1496 * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and 1497 * {@link #CREDENTIAL_TYPE_PASSWORD} 1498 */ getCredentialTypeInternal(int userId)1499 private int getCredentialTypeInternal(int userId) { 1500 if (isSpecialUserId(userId)) { 1501 return mSpManager.getSpecialUserCredentialType(userId); 1502 } 1503 synchronized (mSpManager) { 1504 final long protectorId = getCurrentLskfBasedProtectorId(userId); 1505 if (protectorId == SyntheticPasswordManager.NULL_PROTECTOR_ID) { 1506 // Only possible for new users during early boot (before onThirdPartyAppsStarted()) 1507 return CREDENTIAL_TYPE_NONE; 1508 } 1509 int rawType = mSpManager.getCredentialType(protectorId, userId); 1510 if (rawType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) { 1511 return rawType; 1512 } 1513 return pinOrPasswordQualityToCredentialType(getKeyguardStoredQuality(userId)); 1514 } 1515 } 1516 isUserSecure(int userId)1517 private boolean isUserSecure(int userId) { 1518 return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE; 1519 } 1520 1521 @VisibleForTesting /** Note: this method is overridden in unit tests */ initKeystoreSuperKeys(@serIdInt int userId, SyntheticPassword sp, boolean allowExisting)1522 void initKeystoreSuperKeys(@UserIdInt int userId, SyntheticPassword sp, boolean allowExisting) { 1523 final byte[] password = sp.deriveKeyStorePassword(); 1524 try { 1525 int res = AndroidKeyStoreMaintenance.initUserSuperKeys(userId, password, allowExisting); 1526 if (res != 0) { 1527 throw new IllegalStateException("Failed to initialize Keystore super keys for user " 1528 + userId); 1529 } 1530 } finally { 1531 LockPatternUtils.zeroize(password); 1532 } 1533 } 1534 unlockKeystore(int userId, SyntheticPassword sp)1535 private void unlockKeystore(int userId, SyntheticPassword sp) { 1536 mKeyStoreAuthorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword()); 1537 } 1538 1539 @VisibleForTesting /** Note: this method is overridden in unit tests */ getDecryptedPasswordForTiedProfile(int userId)1540 protected LockscreenCredential getDecryptedPasswordForTiedProfile(int userId) 1541 throws KeyStoreException, UnrecoverableKeyException, 1542 NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, 1543 InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, 1544 CertificateException, IOException { 1545 Slogf.d(TAG, "Decrypting password for tied profile %d", userId); 1546 byte[] storedData = mStorage.readChildProfileLock(userId); 1547 if (storedData == null) { 1548 throw new FileNotFoundException("Child profile lock file not found"); 1549 } 1550 byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE); 1551 byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE, 1552 storedData.length); 1553 byte[] decryptionResult; 1554 SecretKey decryptionKey = (SecretKey) mKeyStore.getKey( 1555 PROFILE_KEY_NAME_DECRYPT + userId, null); 1556 1557 Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" 1558 + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); 1559 1560 cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv)); 1561 decryptionResult = cipher.doFinal(encryptedPassword); 1562 LockscreenCredential credential = LockscreenCredential.createUnifiedProfilePassword( 1563 decryptionResult); 1564 LockPatternUtils.zeroize(decryptionResult); 1565 try { 1566 long parentSid = getGateKeeperService().getSecureUserId( 1567 mUserManager.getProfileParent(userId).id); 1568 mUnifiedProfilePasswordCache.storePassword(userId, credential, parentSid); 1569 } catch (RemoteException e) { 1570 Slogf.w(TAG, "Failed to talk to GateKeeper service", e); 1571 } 1572 return credential; 1573 } 1574 unlockChildProfile(int profileHandle)1575 private void unlockChildProfile(int profileHandle) { 1576 try { 1577 doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle), 1578 profileHandle, null /* progressCallback */, 0 /* flags */); 1579 } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException 1580 | NoSuchAlgorithmException | NoSuchPaddingException 1581 | InvalidAlgorithmParameterException | IllegalBlockSizeException 1582 | BadPaddingException | CertificateException | IOException e) { 1583 if (e instanceof FileNotFoundException) { 1584 Slog.i(TAG, "Child profile key not found"); 1585 } else { 1586 Slog.e(TAG, "Failed to decrypt child profile key", e); 1587 } 1588 } 1589 } 1590 1591 /** 1592 * Unlock the user (both storage and user state) and its associated profiles 1593 * that share lock credential (e.g. managed and clone profiles) synchronously. 1594 * 1595 * <em>Be very careful about the risk of deadlock here: ActivityManager.unlockUser() 1596 * can end up calling into other system services to process user unlock request (via 1597 * {@link com.android.server.SystemServiceManager#unlockUser} </em> 1598 */ unlockUser(@serIdInt int userId)1599 private void unlockUser(@UserIdInt int userId) { 1600 // TODO: make this method fully async so we can update UI with progress strings 1601 final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId); 1602 final CountDownLatch latch = new CountDownLatch(1); 1603 final IProgressListener listener = new IProgressListener.Stub() { 1604 @Override 1605 public void onStarted(int id, Bundle extras) throws RemoteException { 1606 Slog.d(TAG, "unlockUser started"); 1607 } 1608 1609 @Override 1610 public void onProgress(int id, int progress, Bundle extras) throws RemoteException { 1611 Slog.d(TAG, "unlockUser progress " + progress); 1612 } 1613 1614 @Override 1615 public void onFinished(int id, Bundle extras) throws RemoteException { 1616 Slog.d(TAG, "unlockUser finished"); 1617 latch.countDown(); 1618 } 1619 }; 1620 1621 try { 1622 mActivityManager.unlockUser2(userId, listener); 1623 } catch (RemoteException e) { 1624 throw e.rethrowAsRuntimeException(); 1625 } 1626 1627 try { 1628 latch.await(15, TimeUnit.SECONDS); 1629 } catch (InterruptedException e) { 1630 Thread.currentThread().interrupt(); 1631 } 1632 1633 if (isCredentialShareableWithParent(userId)) { 1634 if (!hasUnifiedChallenge(userId)) { 1635 mBiometricDeferredQueue.processPendingLockoutResets(); 1636 } 1637 return; 1638 } 1639 1640 for (UserInfo profile : mUserManager.getProfiles(userId)) { 1641 if (profile.id == userId) continue; 1642 if (!isCredentialShareableWithParent(profile.id)) continue; 1643 1644 if (hasUnifiedChallenge(profile.id)) { 1645 if (mUserManager.isUserRunning(profile.id)) { 1646 // Unlock profile with unified lock 1647 unlockChildProfile(profile.id); 1648 } else { 1649 try { 1650 // Profile not ready for unlock yet, but decrypt the unified challenge now 1651 // so it goes into the cache 1652 getDecryptedPasswordForTiedProfile(profile.id); 1653 } catch (GeneralSecurityException | IOException e) { 1654 Slog.d(TAG, "Cache unified profile password failed", e); 1655 } 1656 } 1657 } 1658 // Now we have unlocked the parent user and attempted to unlock the profile we should 1659 // show notifications if the profile is still locked. 1660 if (!alreadyUnlocked) { 1661 final long ident = clearCallingIdentity(); 1662 try { 1663 maybeShowEncryptionNotificationForUser(profile.id, "parent unlocked"); 1664 } finally { 1665 restoreCallingIdentity(ident); 1666 } 1667 } 1668 } 1669 1670 mBiometricDeferredQueue.processPendingLockoutResets(); 1671 } 1672 hasUnifiedChallenge(int userId)1673 private boolean hasUnifiedChallenge(int userId) { 1674 return !getSeparateProfileChallengeEnabledInternal(userId) 1675 && mStorage.hasChildProfileLock(userId); 1676 } 1677 getDecryptedPasswordsForAllTiedProfiles(int userId)1678 private Map<Integer, LockscreenCredential> getDecryptedPasswordsForAllTiedProfiles(int userId) { 1679 if (isCredentialShareableWithParent(userId)) { 1680 return null; 1681 } 1682 Map<Integer, LockscreenCredential> result = new ArrayMap<>(); 1683 final List<UserInfo> profiles = mUserManager.getProfiles(userId); 1684 final int size = profiles.size(); 1685 for (int i = 0; i < size; i++) { 1686 final UserInfo profile = profiles.get(i); 1687 if (!isCredentialShareableWithParent(profile.id)) { 1688 continue; 1689 } 1690 final int profileUserId = profile.id; 1691 if (getSeparateProfileChallengeEnabledInternal(profileUserId)) { 1692 continue; 1693 } 1694 try { 1695 result.put(profileUserId, getDecryptedPasswordForTiedProfile(profileUserId)); 1696 } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException 1697 | NoSuchPaddingException | InvalidKeyException 1698 | InvalidAlgorithmParameterException | IllegalBlockSizeException 1699 | BadPaddingException | CertificateException | IOException e) { 1700 Slog.e(TAG, "getDecryptedPasswordsForAllTiedProfiles failed for user " + 1701 profileUserId, e); 1702 } 1703 } 1704 return result; 1705 } 1706 1707 /** 1708 * Synchronize all profile's challenge of the given user if it's unified: tie or clear them 1709 * depending on the parent user's secure state. 1710 * 1711 * When clearing tied challenges, a pre-computed password table for profiles are required, since 1712 * changing password for profiles requires existing password, and existing passwords can only be 1713 * computed before the parent user's password is cleared. 1714 * 1715 * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this 1716 * method again on profiles. However the recursion is guaranteed to terminate as this method 1717 * terminates when the user is a profile that shares lock credentials with parent. 1718 * (e.g. managed and clone profile). 1719 */ synchronizeUnifiedChallengeForProfiles(int userId, Map<Integer, LockscreenCredential> profilePasswordMap)1720 private void synchronizeUnifiedChallengeForProfiles(int userId, 1721 Map<Integer, LockscreenCredential> profilePasswordMap) { 1722 if (isCredentialShareableWithParent(userId)) { 1723 return; 1724 } 1725 final boolean isSecure = isUserSecure(userId); 1726 final List<UserInfo> profiles = mUserManager.getProfiles(userId); 1727 final int size = profiles.size(); 1728 for (int i = 0; i < size; i++) { 1729 final UserInfo profile = profiles.get(i); 1730 final int profileUserId = profile.id; 1731 if (isCredentialShareableWithParent(profileUserId)) { 1732 if (getSeparateProfileChallengeEnabledInternal(profileUserId)) { 1733 continue; 1734 } 1735 if (isSecure) { 1736 tieProfileLockIfNecessary(profileUserId, 1737 LockscreenCredential.createNone()); 1738 } else { 1739 // We use cached profile password computed before clearing the parent's 1740 // credential, otherwise they get lost 1741 if (profilePasswordMap != null 1742 && profilePasswordMap.containsKey(profileUserId)) { 1743 setLockCredentialInternal(LockscreenCredential.createNone(), 1744 profilePasswordMap.get(profileUserId), 1745 profileUserId, 1746 /* isLockTiedToParent= */ true); 1747 mStorage.removeChildProfileLock(profileUserId); 1748 removeKeystoreProfileKey(profileUserId); 1749 } else { 1750 Slog.wtf(TAG, "Attempt to clear tied challenge, but no password supplied."); 1751 } 1752 } 1753 } 1754 } 1755 } 1756 isProfileWithUnifiedLock(int userId)1757 private boolean isProfileWithUnifiedLock(int userId) { 1758 return isCredentialShareableWithParent(userId) 1759 && !getSeparateProfileChallengeEnabledInternal(userId); 1760 } 1761 1762 /** 1763 * Send credentials for user {@code userId} to {@link RecoverableKeyStoreManager} during an 1764 * unlock operation. 1765 */ sendCredentialsOnUnlockIfRequired(LockscreenCredential credential, int userId)1766 private void sendCredentialsOnUnlockIfRequired(LockscreenCredential credential, int userId) { 1767 // Don't send credentials during the special user flow. 1768 if (isSpecialUserId(userId)) { 1769 return; 1770 } 1771 1772 // Don't send empty credentials on unlock. 1773 if (credential.isNone()) { 1774 return; 1775 } 1776 1777 // A profile with a unified lock screen stores a randomly generated credential, so skip it. 1778 // Its parent will send credentials for the profile, as it stores the unified lock 1779 // credential. 1780 if (isProfileWithUnifiedLock(userId)) { 1781 return; 1782 } 1783 1784 // Send credentials for the user and any child profiles that share its lock screen. 1785 for (int profileId : getProfilesWithSameLockScreen(userId)) { 1786 mRecoverableKeyStoreManager.lockScreenSecretAvailable( 1787 credential.getType(), credential.getCredential(), profileId); 1788 } 1789 } 1790 1791 /** 1792 * Send credentials for user {@code userId} to {@link RecoverableKeyStoreManager} when its 1793 * credentials are set/changed. 1794 */ sendCredentialsOnChangeIfRequired( LockscreenCredential credential, int userId, boolean isLockTiedToParent)1795 private void sendCredentialsOnChangeIfRequired( 1796 LockscreenCredential credential, int userId, boolean isLockTiedToParent) { 1797 // A profile whose lock screen is being tied to its parent's will either have a randomly 1798 // generated credential (creation) or null (removal). We rely on the parent to send its 1799 // credentials for the profile in both cases as it stores the unified lock credential. 1800 if (isLockTiedToParent) { 1801 return; 1802 } 1803 1804 // RecoverableKeyStoreManager expects null for empty credential. 1805 final byte[] secret = credential.isNone() ? null : credential.getCredential(); 1806 // Send credentials for the user and any child profiles that share its lock screen. 1807 for (int profileId : getProfilesWithSameLockScreen(userId)) { 1808 mRecoverableKeyStoreManager.lockScreenSecretChanged( 1809 credential.getType(), secret, profileId); 1810 } 1811 } 1812 1813 /** 1814 * Returns all profiles of {@code userId}, including itself, that have the same lock screen 1815 * challenge. 1816 */ getProfilesWithSameLockScreen(int userId)1817 private Set<Integer> getProfilesWithSameLockScreen(int userId) { 1818 Set<Integer> profiles = new ArraySet<>(); 1819 for (UserInfo profile : mUserManager.getProfiles(userId)) { 1820 if (profile.id == userId 1821 || (profile.profileGroupId == userId 1822 && isProfileWithUnifiedLock(profile.id))) { 1823 profiles.add(profile.id); 1824 } 1825 } 1826 return profiles; 1827 } 1828 1829 // This method should be called by LockPatternUtil only, all internal methods in this class 1830 // should call setLockCredentialInternal. 1831 @Override setLockCredential(LockscreenCredential credential, LockscreenCredential savedCredential, int userId)1832 public boolean setLockCredential(LockscreenCredential credential, 1833 LockscreenCredential savedCredential, int userId) { 1834 1835 if (!mHasSecureLockScreen 1836 && credential != null && credential.getType() != CREDENTIAL_TYPE_NONE) { 1837 throw new UnsupportedOperationException( 1838 "This operation requires secure lock screen feature"); 1839 } 1840 if (!hasPermission(PERMISSION) && !hasPermission(SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS)) { 1841 if (hasPermission(SET_INITIAL_LOCK) && savedCredential.isNone()) { 1842 // SET_INITIAL_LOCK can only be used if credential is not set. 1843 } else { 1844 throw new SecurityException( 1845 "setLockCredential requires SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS or " 1846 + PERMISSION); 1847 } 1848 } 1849 credential.validateBasicRequirements(); 1850 1851 final long identity = Binder.clearCallingIdentity(); 1852 try { 1853 enforceFrpNotActive(); 1854 // When changing credential for profiles with unified challenge, some callers 1855 // will pass in empty credential while others will pass in the credential of 1856 // the parent user. setLockCredentialInternal() handles the formal case (empty 1857 // credential) correctly but not the latter. As a stopgap fix, convert the latter 1858 // case to the formal. The long-term fix would be fixing LSS such that it should 1859 // accept only the parent user credential on its public API interfaces, swap it 1860 // with the profile's random credential at that API boundary (i.e. here) and make 1861 // sure LSS internally does not special case profile with unififed challenge: b/80170828 1862 if (!savedCredential.isNone() && isProfileWithUnifiedLock(userId)) { 1863 // Verify the parent credential again, to make sure we have a fresh enough 1864 // auth token such that getDecryptedPasswordForTiedProfile() inside 1865 // setLockCredentialInternal() can function correctly. 1866 verifyCredential(savedCredential, mUserManager.getProfileParent(userId).id, 1867 0 /* flags */); 1868 savedCredential.zeroize(); 1869 savedCredential = LockscreenCredential.createNone(); 1870 } 1871 synchronized (mSeparateChallengeLock) { 1872 if (!setLockCredentialInternal(credential, savedCredential, 1873 userId, /* isLockTiedToParent= */ false)) { 1874 scheduleGc(); 1875 return false; 1876 } 1877 setSeparateProfileChallengeEnabledLocked(userId, true, /* unused */ null); 1878 notifyPasswordChanged(credential, userId); 1879 } 1880 if (isCredentialShareableWithParent(userId)) { 1881 // Make sure the profile doesn't get locked straight after setting challenge. 1882 setDeviceUnlockedForUser(userId); 1883 } 1884 notifySeparateProfileChallengeChanged(userId); 1885 onPostPasswordChanged(credential, userId); 1886 scheduleGc(); 1887 return true; 1888 } finally { 1889 Binder.restoreCallingIdentity(identity); 1890 } 1891 } 1892 1893 @Override writeRepairModeCredential(int userId)1894 public boolean writeRepairModeCredential(int userId) { 1895 checkWritePermission(); 1896 final long identity = Binder.clearCallingIdentity(); 1897 try { 1898 synchronized (mSpManager) { 1899 long protectorId = getCurrentLskfBasedProtectorId(userId); 1900 return mSpManager.writeRepairModeCredentialLocked(protectorId, userId); 1901 } 1902 } finally { 1903 Binder.restoreCallingIdentity(identity); 1904 } 1905 } 1906 1907 /** 1908 * Set a new LSKF for the given user/profile. Only succeeds if the synthetic password for the 1909 * user is protected by the given {@param savedCredential}. 1910 * <p> 1911 * When {@link android.security.Flags#clearStrongAuthOnAddingPrimaryCredential()} is enabled and 1912 * setting a new credential where there was none, updates the strong auth state for 1913 * {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>. 1914 * 1915 * @param savedCredential if the user is a profile with unified challenge and savedCredential is 1916 * empty, LSS will try to re-derive the profile password internally. 1917 * TODO (b/80170828): Fix this so profile password is always passed in. 1918 * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new 1919 * credentials are being tied to its parent's credentials. 1920 */ setLockCredentialInternal(LockscreenCredential credential, LockscreenCredential savedCredential, int userId, boolean isLockTiedToParent)1921 private boolean setLockCredentialInternal(LockscreenCredential credential, 1922 LockscreenCredential savedCredential, int userId, boolean isLockTiedToParent) { 1923 Objects.requireNonNull(credential); 1924 Objects.requireNonNull(savedCredential); 1925 synchronized (mSpManager) { 1926 if (savedCredential.isNone() && isProfileWithUnifiedLock(userId)) { 1927 // get credential from keystore when profile has unified lock 1928 try { 1929 //TODO: remove as part of b/80170828 1930 savedCredential = getDecryptedPasswordForTiedProfile(userId); 1931 } catch (FileNotFoundException e) { 1932 Slog.i(TAG, "Child profile key not found"); 1933 } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException 1934 | NoSuchAlgorithmException | NoSuchPaddingException 1935 | InvalidAlgorithmParameterException | IllegalBlockSizeException 1936 | BadPaddingException | CertificateException | IOException e) { 1937 Slog.e(TAG, "Failed to decrypt child profile key", e); 1938 } 1939 } 1940 final long oldProtectorId = getCurrentLskfBasedProtectorId(userId); 1941 AuthenticationResult authResult = mSpManager.unlockLskfBasedProtector( 1942 getGateKeeperService(), oldProtectorId, savedCredential, userId, null); 1943 VerifyCredentialResponse response = authResult.gkResponse; 1944 SyntheticPassword sp = authResult.syntheticPassword; 1945 1946 if (sp == null) { 1947 if (response == null 1948 || response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) { 1949 Slog.w(TAG, "Failed to enroll: incorrect credential."); 1950 return false; 1951 } 1952 if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { 1953 Slog.w(TAG, "Failed to enroll: rate limit exceeded."); 1954 return false; 1955 } 1956 // Should not be reachable, but just in case. 1957 throw new IllegalStateException("password change failed"); 1958 } 1959 1960 onSyntheticPasswordUnlocked(userId, sp); 1961 setLockCredentialWithSpLocked(credential, sp, userId); 1962 if (android.security.Flags.clearStrongAuthOnAddingPrimaryCredential() 1963 && savedCredential.isNone() && !credential.isNone()) { 1964 // Clear the strong auth value, since the LSKF has just been entered and set, 1965 // but only when the previous credential was None. 1966 mStrongAuth.reportUnlock(userId); 1967 } 1968 sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent); 1969 return true; 1970 } 1971 } 1972 onPostPasswordChanged(LockscreenCredential newCredential, int userId)1973 private void onPostPasswordChanged(LockscreenCredential newCredential, int userId) { 1974 updatePasswordHistory(newCredential, userId); 1975 mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userId); 1976 sendMainUserCredentialChangedNotificationIfNeeded(userId); 1977 } 1978 1979 /** 1980 * Store the hash of the new password in the password history list, if device policy enforces 1981 * a password history requirement. 1982 * 1983 * This must not be called while the mSpManager lock is held, as this calls into 1984 * DevicePolicyManagerService to get the requested password history length. 1985 */ updatePasswordHistory(LockscreenCredential password, int userHandle)1986 private void updatePasswordHistory(LockscreenCredential password, int userHandle) { 1987 if (password.isNone()) { 1988 return; 1989 } 1990 if (password.isPattern()) { 1991 // Do not keep track of historical patterns 1992 return; 1993 } 1994 // Add the password to the password history. 1995 String passwordHistory = getString( 1996 LockPatternUtils.PASSWORD_HISTORY_KEY, /* defaultValue= */ null, userHandle); 1997 if (passwordHistory == null) { 1998 passwordHistory = ""; 1999 } 2000 int passwordHistoryLength = getRequestedPasswordHistoryLength(userHandle); 2001 if (passwordHistoryLength == 0) { 2002 passwordHistory = ""; 2003 } else { 2004 Slogf.d(TAG, "Adding new password to password history for user %d", userHandle); 2005 final byte[] hashFactor = getHashFactor(password, userHandle); 2006 final byte[] salt = getSalt(userHandle).getBytes(); 2007 String hash = password.passwordToHistoryHash(salt, hashFactor); 2008 if (hash == null) { 2009 // This should never happen, as all information needed to compute the hash should be 2010 // available. In particular, unwrapping the SP in getHashFactor() should always 2011 // succeed, as we're using the LSKF that was just set. 2012 Slog.e(TAG, "Failed to compute password hash; password history won't be updated"); 2013 return; 2014 } 2015 if (TextUtils.isEmpty(passwordHistory)) { 2016 passwordHistory = hash; 2017 } else { 2018 String[] history = passwordHistory.split( 2019 LockPatternUtils.PASSWORD_HISTORY_DELIMITER); 2020 StringJoiner joiner = new StringJoiner(LockPatternUtils.PASSWORD_HISTORY_DELIMITER); 2021 joiner.add(hash); 2022 for (int i = 0; i < passwordHistoryLength - 1 && i < history.length; i++) { 2023 joiner.add(history[i]); 2024 } 2025 passwordHistory = joiner.toString(); 2026 } 2027 } 2028 setString(LockPatternUtils.PASSWORD_HISTORY_KEY, passwordHistory, userHandle); 2029 } 2030 getSalt(int userId)2031 private String getSalt(int userId) { 2032 long salt = getLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, 0, userId); 2033 if (salt == 0) { 2034 salt = SecureRandomUtils.randomLong(); 2035 setLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, salt, userId); 2036 } 2037 return Long.toHexString(salt); 2038 } 2039 getRequestedPasswordHistoryLength(int userId)2040 private int getRequestedPasswordHistoryLength(int userId) { 2041 return mInjector.getDevicePolicyManager().getPasswordHistoryLength(null, userId); 2042 } 2043 getUserProperties(int userId)2044 private @Nullable UserProperties getUserProperties(int userId) { 2045 return mInjector.getUserManagerInternal().getUserProperties(userId); 2046 } 2047 2048 @VisibleForTesting /** Note: this method is overridden in unit tests */ isCredentialShareableWithParent(int userId)2049 protected boolean isCredentialShareableWithParent(int userId) { 2050 UserProperties props = getUserProperties(userId); 2051 return props != null && props.isCredentialShareableWithParent(); 2052 } 2053 2054 /** Register the given WeakEscrowTokenRemovedListener. */ 2055 @Override registerWeakEscrowTokenRemovedListener( @onNull IWeakEscrowTokenRemovedListener listener)2056 public boolean registerWeakEscrowTokenRemovedListener( 2057 @NonNull IWeakEscrowTokenRemovedListener listener) { 2058 checkManageWeakEscrowTokenMethodUsage(); 2059 final long token = Binder.clearCallingIdentity(); 2060 try { 2061 return mSpManager.registerWeakEscrowTokenRemovedListener(listener); 2062 } finally { 2063 Binder.restoreCallingIdentity(token); 2064 } 2065 } 2066 2067 /** Unregister the given WeakEscrowTokenRemovedListener. */ 2068 @Override unregisterWeakEscrowTokenRemovedListener( @onNull IWeakEscrowTokenRemovedListener listener)2069 public boolean unregisterWeakEscrowTokenRemovedListener( 2070 @NonNull IWeakEscrowTokenRemovedListener listener) { 2071 checkManageWeakEscrowTokenMethodUsage(); 2072 final long token = Binder.clearCallingIdentity(); 2073 try { 2074 return mSpManager.unregisterWeakEscrowTokenRemovedListener(listener); 2075 } finally { 2076 Binder.restoreCallingIdentity(token); 2077 } 2078 } 2079 2080 @Override addWeakEscrowToken(byte[] token, int userId, @NonNull IWeakEscrowTokenActivatedListener listener)2081 public long addWeakEscrowToken(byte[] token, int userId, 2082 @NonNull IWeakEscrowTokenActivatedListener listener) { 2083 checkManageWeakEscrowTokenMethodUsage(); 2084 Objects.requireNonNull(listener, "Listener can not be null."); 2085 EscrowTokenStateChangeCallback internalListener = (handle, userId1) -> { 2086 try { 2087 listener.onWeakEscrowTokenActivated(handle, userId1); 2088 } catch (RemoteException e) { 2089 Slog.e(TAG, "Exception while notifying weak escrow token has been activated", e); 2090 } 2091 }; 2092 final long restoreToken = Binder.clearCallingIdentity(); 2093 try { 2094 return addEscrowToken(token, TOKEN_TYPE_WEAK, userId, internalListener); 2095 } finally { 2096 Binder.restoreCallingIdentity(restoreToken); 2097 } 2098 } 2099 2100 @Override removeWeakEscrowToken(long handle, int userId)2101 public boolean removeWeakEscrowToken(long handle, int userId) { 2102 checkManageWeakEscrowTokenMethodUsage(); 2103 final long token = Binder.clearCallingIdentity(); 2104 try { 2105 return removeEscrowToken(handle, userId); 2106 } finally { 2107 Binder.restoreCallingIdentity(token); 2108 } 2109 } 2110 2111 @Override isWeakEscrowTokenActive(long handle, int userId)2112 public boolean isWeakEscrowTokenActive(long handle, int userId) { 2113 checkManageWeakEscrowTokenMethodUsage(); 2114 final long token = Binder.clearCallingIdentity(); 2115 try { 2116 return isEscrowTokenActive(handle, userId); 2117 } finally { 2118 Binder.restoreCallingIdentity(token); 2119 } 2120 } 2121 2122 @Override isWeakEscrowTokenValid(long handle, byte[] token, int userId)2123 public boolean isWeakEscrowTokenValid(long handle, byte[] token, int userId) { 2124 checkManageWeakEscrowTokenMethodUsage(); 2125 final long restoreToken = Binder.clearCallingIdentity(); 2126 try { 2127 synchronized (mSpManager) { 2128 if (!mSpManager.hasEscrowData(userId)) { 2129 Slog.w(TAG, "Escrow token is disabled on the current user"); 2130 return false; 2131 } 2132 AuthenticationResult authResult = mSpManager.unlockWeakTokenBasedProtector( 2133 getGateKeeperService(), handle, token, userId); 2134 if (authResult.syntheticPassword == null) { 2135 Slog.w(TAG, "Invalid escrow token supplied"); 2136 return false; 2137 } 2138 return true; 2139 } 2140 } finally { 2141 Binder.restoreCallingIdentity(restoreToken); 2142 } 2143 } 2144 2145 @VisibleForTesting /** Note: this method is overridden in unit tests */ tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password)2146 protected void tieProfileLockToParent(int profileUserId, int parentUserId, 2147 LockscreenCredential password) { 2148 Slogf.i(TAG, "Tying lock for profile user %d to parent user %d", profileUserId, 2149 parentUserId); 2150 final byte[] iv; 2151 final byte[] ciphertext; 2152 final long parentSid; 2153 try { 2154 parentSid = getGateKeeperService().getSecureUserId(parentUserId); 2155 } catch (RemoteException e) { 2156 throw new IllegalStateException("Failed to talk to GateKeeper service", e); 2157 } 2158 2159 try { 2160 KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); 2161 keyGenerator.init(new SecureRandom()); 2162 SecretKey secretKey = keyGenerator.generateKey(); 2163 try { 2164 mKeyStore.setEntry( 2165 PROFILE_KEY_NAME_ENCRYPT + profileUserId, 2166 new KeyStore.SecretKeyEntry(secretKey), 2167 new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) 2168 .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 2169 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 2170 .build()); 2171 mKeyStore.setEntry( 2172 PROFILE_KEY_NAME_DECRYPT + profileUserId, 2173 new KeyStore.SecretKeyEntry(secretKey), 2174 new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) 2175 .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 2176 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 2177 .setUserAuthenticationRequired(true) 2178 .setBoundToSpecificSecureUserId(parentSid) 2179 .setUserAuthenticationValidityDurationSeconds(30) 2180 .build()); 2181 // Key imported, obtain a reference to it. 2182 SecretKey keyStoreEncryptionKey = (SecretKey) mKeyStore.getKey( 2183 PROFILE_KEY_NAME_ENCRYPT + profileUserId, null); 2184 Cipher cipher = Cipher.getInstance( 2185 KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" 2186 + KeyProperties.ENCRYPTION_PADDING_NONE); 2187 cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey); 2188 ciphertext = cipher.doFinal(password.getCredential()); 2189 iv = cipher.getIV(); 2190 } finally { 2191 // The original key can now be discarded. 2192 mKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId); 2193 } 2194 } catch (UnrecoverableKeyException 2195 | BadPaddingException | IllegalBlockSizeException | KeyStoreException 2196 | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) { 2197 throw new IllegalStateException("Failed to encrypt key", e); 2198 } 2199 if (iv.length != PROFILE_KEY_IV_SIZE) { 2200 throw new IllegalArgumentException("Invalid iv length: " + iv.length); 2201 } 2202 mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext)); 2203 } 2204 setCeStorageProtection(@serIdInt int userId, SyntheticPassword sp)2205 private void setCeStorageProtection(@UserIdInt int userId, SyntheticPassword sp) { 2206 final byte[] secret = sp.deriveFileBasedEncryptionKey(); 2207 final long callingId = Binder.clearCallingIdentity(); 2208 try { 2209 mStorageManager.setCeStorageProtection(userId, secret); 2210 } catch (RemoteException e) { 2211 throw new IllegalStateException("Failed to protect CE key for user " + userId, e); 2212 } finally { 2213 Binder.restoreCallingIdentity(callingId); 2214 } 2215 } 2216 isCeStorageUnlocked(int userId)2217 private boolean isCeStorageUnlocked(int userId) { 2218 try { 2219 return mStorageManager.isCeStorageUnlocked(userId); 2220 } catch (RemoteException e) { 2221 Slog.e(TAG, "Error checking whether CE storage is unlocked", e); 2222 return false; 2223 } 2224 } 2225 2226 /** 2227 * Unlocks the user's CE (credential-encrypted) storage if it's not already unlocked. 2228 * <p> 2229 * This method doesn't throw exceptions because it is called opportunistically whenever a user 2230 * is started. Whether it worked or not can be detected by whether the key got unlocked or not. 2231 */ unlockCeStorage(@serIdInt int userId, SyntheticPassword sp)2232 private void unlockCeStorage(@UserIdInt int userId, SyntheticPassword sp) { 2233 if (isCeStorageUnlocked(userId)) { 2234 Slogf.d(TAG, "CE storage for user %d is already unlocked", userId); 2235 return; 2236 } 2237 final String userType = isUserSecure(userId) ? "secured" : "unsecured"; 2238 final byte[] secret = sp.deriveFileBasedEncryptionKey(); 2239 try { 2240 mStorageManager.unlockCeStorage(userId, secret); 2241 Slogf.i(TAG, "Unlocked CE storage for %s user %d", userType, userId); 2242 } catch (RemoteException e) { 2243 Slogf.wtf(TAG, e, "Failed to unlock CE storage for %s user %d", userType, userId); 2244 } finally { 2245 LockPatternUtils.zeroize(secret); 2246 } 2247 } 2248 2249 @Override unlockUserKeyIfUnsecured(@serIdInt int userId)2250 public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { 2251 checkPasswordReadPermission(); 2252 synchronized (mSpManager) { 2253 if (isCeStorageUnlocked(userId)) { 2254 Slogf.d(TAG, "CE storage for user %d is already unlocked", userId); 2255 // This method actually does more than unlock CE storage. However, if CE storage is 2256 // already unlocked, then the other parts must have already been done too. 2257 return; 2258 } 2259 if (isUserSecure(userId)) { 2260 Slogf.d(TAG, "Not unlocking CE storage for user %d yet because user is secured", 2261 userId); 2262 return; 2263 } 2264 Slogf.i(TAG, "Unwrapping synthetic password for unsecured user %d", userId); 2265 AuthenticationResult result = mSpManager.unlockLskfBasedProtector( 2266 getGateKeeperService(), getCurrentLskfBasedProtectorId(userId), 2267 LockscreenCredential.createNone(), userId, null); 2268 if (result.syntheticPassword == null) { 2269 Slogf.wtf(TAG, "Failed to unwrap synthetic password for unsecured user %d", userId); 2270 return; 2271 } 2272 onSyntheticPasswordUnlocked(userId, result.syntheticPassword); 2273 unlockKeystore(userId, result.syntheticPassword); 2274 unlockCeStorage(userId, result.syntheticPassword); 2275 } 2276 } 2277 2278 @Override resetKeyStore(int userId)2279 public void resetKeyStore(int userId) { 2280 checkWritePermission(); 2281 Slogf.d(TAG, "Resetting keystore for user %d", userId); 2282 List<Integer> profileUserIds = new ArrayList<>(); 2283 List<LockscreenCredential> profileUserDecryptedPasswords = new ArrayList<>(); 2284 final List<UserInfo> profiles = mUserManager.getProfiles(userId); 2285 for (UserInfo pi : profiles) { 2286 // Unlock profile which shares credential with parent with unified lock 2287 if (isCredentialShareableWithParent(pi.id) 2288 && !getSeparateProfileChallengeEnabledInternal(pi.id) 2289 && mStorage.hasChildProfileLock(pi.id)) { 2290 try { 2291 profileUserDecryptedPasswords.add(getDecryptedPasswordForTiedProfile(pi.id)); 2292 profileUserIds.add(pi.id); 2293 } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException 2294 | NoSuchAlgorithmException | NoSuchPaddingException 2295 | InvalidAlgorithmParameterException | IllegalBlockSizeException 2296 | BadPaddingException | CertificateException | IOException e) { 2297 Slog.e(TAG, "Failed to decrypt child profile key", e); 2298 } 2299 } 2300 } 2301 try { 2302 // Clear all the users credentials could have been installed in for this user. 2303 for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) { 2304 for (int uid : SYSTEM_CREDENTIAL_UIDS) { 2305 AndroidKeyStoreMaintenance.clearNamespace(Domain.APP, 2306 UserHandle.getUid(profileId, uid)); 2307 } 2308 } 2309 if (mUserManager.getUserInfo(userId).isPrimary()) { 2310 AndroidKeyStoreMaintenance.clearNamespace(Domain.SELINUX, 2311 KeyProperties.NAMESPACE_WIFI); 2312 } 2313 } finally { 2314 for (int i = 0; i < profileUserIds.size(); ++i) { 2315 int piUserId = profileUserIds.get(i); 2316 LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); 2317 if (piUserId != -1 && piUserDecryptedPassword != null) { 2318 tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword); 2319 } 2320 if (piUserDecryptedPassword != null) { 2321 piUserDecryptedPassword.zeroize(); 2322 } 2323 } 2324 } 2325 } 2326 2327 @Override checkCredential(LockscreenCredential credential, int userId, ICheckCredentialProgressCallback progressCallback)2328 public VerifyCredentialResponse checkCredential(LockscreenCredential credential, int userId, 2329 ICheckCredentialProgressCallback progressCallback) { 2330 checkPasswordReadPermission(); 2331 final long identity = Binder.clearCallingIdentity(); 2332 try { 2333 return doVerifyCredential(credential, userId, progressCallback, 0 /* flags */); 2334 } finally { 2335 Binder.restoreCallingIdentity(identity); 2336 scheduleGc(); 2337 } 2338 } 2339 2340 @Override 2341 @Nullable verifyCredential(LockscreenCredential credential, int userId, int flags)2342 public VerifyCredentialResponse verifyCredential(LockscreenCredential credential, 2343 int userId, int flags) { 2344 if (!hasPermission(PERMISSION) && !hasPermission(SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS)) { 2345 throw new SecurityException( 2346 "verifyCredential requires SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS or " 2347 + PERMISSION); 2348 } 2349 final long identity = Binder.clearCallingIdentity(); 2350 try { 2351 return doVerifyCredential(credential, userId, null /* progressCallback */, flags); 2352 } finally { 2353 Binder.restoreCallingIdentity(identity); 2354 scheduleGc(); 2355 } 2356 } 2357 2358 @Override verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, long challenge, int userId)2359 public VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, 2360 long challenge, int userId) { 2361 2362 checkPasswordReadPermission(); 2363 2364 final VerifyCredentialResponse response; 2365 final byte[] gatekeeperPassword; 2366 2367 synchronized (mGatekeeperPasswords) { 2368 gatekeeperPassword = mGatekeeperPasswords.get(gatekeeperPasswordHandle); 2369 } 2370 2371 synchronized (mSpManager) { 2372 if (gatekeeperPassword == null) { 2373 Slog.d(TAG, "No gatekeeper password for handle"); 2374 response = VerifyCredentialResponse.ERROR; 2375 } else { 2376 response = mSpManager.verifyChallengeInternal(getGateKeeperService(), 2377 gatekeeperPassword, challenge, userId); 2378 } 2379 } 2380 return response; 2381 } 2382 2383 @Override removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle)2384 public void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle) { 2385 checkPasswordReadPermission(); 2386 synchronized (mGatekeeperPasswords) { 2387 mGatekeeperPasswords.remove(gatekeeperPasswordHandle); 2388 } 2389 } 2390 2391 /** 2392 * Verify user credential and unlock the user. 2393 * @param credential User's lockscreen credential 2394 * @param userId User to verify the credential for 2395 * @param progressCallback Receive progress callbacks 2396 * @param flags See {@link LockPatternUtils.VerifyFlag} 2397 * @return See {@link VerifyCredentialResponse} 2398 */ doVerifyCredential(LockscreenCredential credential, int userId, ICheckCredentialProgressCallback progressCallback, @LockPatternUtils.VerifyFlag int flags)2399 private VerifyCredentialResponse doVerifyCredential(LockscreenCredential credential, 2400 int userId, ICheckCredentialProgressCallback progressCallback, 2401 @LockPatternUtils.VerifyFlag int flags) { 2402 if (credential == null || credential.isNone()) { 2403 throw new IllegalArgumentException("Credential can't be null or empty"); 2404 } 2405 if (userId == USER_FRP && Settings.Global.getInt(mContext.getContentResolver(), 2406 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2407 Slog.e(TAG, "FRP credential can only be verified prior to provisioning."); 2408 return VerifyCredentialResponse.ERROR; 2409 } 2410 if (userId == USER_REPAIR_MODE && !LockPatternUtils.isRepairModeActive(mContext)) { 2411 Slog.e(TAG, "Repair mode is not active on the device."); 2412 return VerifyCredentialResponse.ERROR; 2413 } 2414 Slogf.i(TAG, "Verifying lockscreen credential for user %d", userId); 2415 2416 final AuthenticationResult authResult; 2417 VerifyCredentialResponse response; 2418 2419 synchronized (mSpManager) { 2420 if (isSpecialUserId(userId)) { 2421 response = mSpManager.verifySpecialUserCredential(userId, getGateKeeperService(), 2422 credential, progressCallback); 2423 if (android.security.Flags.frpEnforcement() && response.isMatched() 2424 && userId == USER_FRP) { 2425 mStorage.deactivateFactoryResetProtectionWithoutSecret(); 2426 } 2427 return response; 2428 } 2429 2430 long protectorId = getCurrentLskfBasedProtectorId(userId); 2431 authResult = mSpManager.unlockLskfBasedProtector( 2432 getGateKeeperService(), protectorId, credential, userId, progressCallback); 2433 response = authResult.gkResponse; 2434 2435 if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { 2436 if ((flags & VERIFY_FLAG_WRITE_REPAIR_MODE_PW) != 0) { 2437 if (!mSpManager.writeRepairModeCredentialLocked(protectorId, userId)) { 2438 Slog.e(TAG, "Failed to write repair mode credential"); 2439 return VerifyCredentialResponse.ERROR; 2440 } 2441 } 2442 // credential has matched 2443 mBiometricDeferredQueue.addPendingLockoutResetForUser(userId, 2444 authResult.syntheticPassword.deriveGkPassword()); 2445 } 2446 } 2447 if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { 2448 Slogf.i(TAG, "Successfully verified lockscreen credential for user %d", userId); 2449 onCredentialVerified(authResult.syntheticPassword, 2450 PasswordMetrics.computeForCredential(credential), userId); 2451 if ((flags & VERIFY_FLAG_REQUEST_GK_PW_HANDLE) != 0) { 2452 final long gkHandle = storeGatekeeperPasswordTemporarily( 2453 authResult.syntheticPassword.deriveGkPassword()); 2454 response = new VerifyCredentialResponse.Builder() 2455 .setGatekeeperPasswordHandle(gkHandle) 2456 .build(); 2457 } 2458 sendCredentialsOnUnlockIfRequired(credential, userId); 2459 } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { 2460 if (response.getTimeout() > 0) { 2461 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); 2462 } 2463 } 2464 final boolean success = response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK; 2465 notifyLockSettingsStateListeners(success, userId); 2466 return response; 2467 } 2468 notifyLockSettingsStateListeners(boolean success, int userId)2469 private void notifyLockSettingsStateListeners(boolean success, int userId) { 2470 for (LockSettingsStateListener listener : mLockSettingsStateListeners) { 2471 if (success) { 2472 listener.onAuthenticationSucceeded(userId); 2473 } else { 2474 listener.onAuthenticationFailed(userId); 2475 } 2476 } 2477 } 2478 2479 @Override verifyTiedProfileChallenge(LockscreenCredential credential, int userId, @LockPatternUtils.VerifyFlag int flags)2480 public VerifyCredentialResponse verifyTiedProfileChallenge(LockscreenCredential credential, 2481 int userId, @LockPatternUtils.VerifyFlag int flags) { 2482 checkPasswordReadPermission(); 2483 Slogf.i(TAG, "Verifying tied profile challenge for user %d", userId); 2484 2485 if (!isProfileWithUnifiedLock(userId)) { 2486 throw new IllegalArgumentException( 2487 "User id must be managed/clone profile with unified lock"); 2488 } 2489 final int parentProfileId = mUserManager.getProfileParent(userId).id; 2490 // Unlock parent by using parent's challenge 2491 final VerifyCredentialResponse parentResponse = doVerifyCredential( 2492 credential, 2493 parentProfileId, 2494 null /* progressCallback */, 2495 flags); 2496 if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { 2497 // Failed, just return parent's response 2498 return parentResponse; 2499 } 2500 2501 try { 2502 // Unlock profile with unified lock 2503 return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId), 2504 userId, null /* progressCallback */, flags); 2505 } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException 2506 | NoSuchAlgorithmException | NoSuchPaddingException 2507 | InvalidAlgorithmParameterException | IllegalBlockSizeException 2508 | BadPaddingException | CertificateException | IOException e) { 2509 Slog.e(TAG, "Failed to decrypt child profile key", e); 2510 throw new IllegalStateException("Unable to get tied profile token"); 2511 } finally { 2512 scheduleGc(); 2513 } 2514 } 2515 2516 /** 2517 * Keep track of the given user's latest password metric. This should be called 2518 * when the user is authenticating or when a new password is being set. In comparison, 2519 * {@link #notifyPasswordChanged} only needs to be called when the user changes the password. 2520 */ setUserPasswordMetrics(LockscreenCredential password, @UserIdInt int userHandle)2521 private void setUserPasswordMetrics(LockscreenCredential password, @UserIdInt int userHandle) { 2522 synchronized (this) { 2523 mUserPasswordMetrics.put(userHandle, PasswordMetrics.computeForCredential(password)); 2524 } 2525 } 2526 2527 /** 2528 * Returns the PasswordMetrics for the current user 2529 * @param userHandle The id of the user for which we return the password metrics object 2530 * @return passwordmetrics for the user or null if not available 2531 */ 2532 @VisibleForTesting getUserPasswordMetrics(int userHandle)2533 PasswordMetrics getUserPasswordMetrics(int userHandle) { 2534 if (!isUserSecure(userHandle)) { 2535 // for users without password, mUserPasswordMetrics might not be initialized 2536 // since the user never unlock the device manually. In this case, always 2537 // return a default metrics object. This is to distinguish this case from 2538 // the case where during boot user password is unknown yet (returning null here) 2539 return new PasswordMetrics(CREDENTIAL_TYPE_NONE); 2540 } 2541 synchronized (this) { 2542 return mUserPasswordMetrics.get(userHandle); 2543 } 2544 } 2545 loadPasswordMetrics(SyntheticPassword sp, int userHandle)2546 private @Nullable PasswordMetrics loadPasswordMetrics(SyntheticPassword sp, int userHandle) { 2547 synchronized (mSpManager) { 2548 if (!isUserSecure(userHandle)) { 2549 return null; 2550 } 2551 return mSpManager.getPasswordMetrics(sp, getCurrentLskfBasedProtectorId(userHandle), 2552 userHandle); 2553 } 2554 } 2555 2556 /** 2557 * Call after {@link #setUserPasswordMetrics} so metrics are updated before 2558 * reporting the password changed. 2559 */ notifyPasswordChanged(LockscreenCredential newCredential, @UserIdInt int userId)2560 private void notifyPasswordChanged(LockscreenCredential newCredential, @UserIdInt int userId) { 2561 mHandler.post(() -> { 2562 mInjector.getDevicePolicyManager().reportPasswordChanged( 2563 PasswordMetrics.computeForCredential(newCredential), 2564 userId); 2565 LocalServices.getService(WindowManagerInternal.class).reportPasswordChanged(userId); 2566 }); 2567 } 2568 createNewUser(@serIdInt int userId, int userSerialNumber)2569 private void createNewUser(@UserIdInt int userId, int userSerialNumber) { 2570 2571 // Delete all Keystore keys for userId, just in case any were left around from a removed 2572 // user with the same userId. This should be unnecessary, but we've been doing this for a 2573 // long time, so for now we keep doing it just in case it's ever important. Don't wait 2574 // until initKeystoreSuperKeys() to do this; that can be delayed if the user is being 2575 // created during early boot, and maybe something will use Keystore before then. 2576 AndroidKeyStoreMaintenance.onUserAdded(userId); 2577 2578 synchronized (mUserCreationAndRemovalLock) { 2579 // During early boot, don't actually create the synthetic password yet, but rather 2580 // automatically delay it to later. We do this because protecting the synthetic 2581 // password requires the Weaver HAL if the device supports it, and some devices don't 2582 // make Weaver available until fairly late in the boot process. This logic ensures a 2583 // consistent flow across all devices, regardless of their Weaver implementation. 2584 if (!mThirdPartyAppsStarted) { 2585 Slogf.i(TAG, "Delaying locksettings state creation for user %d until third-party " + 2586 "apps are started", userId); 2587 mEarlyCreatedUsers.put(userId, userSerialNumber); 2588 mEarlyRemovedUsers.delete(userId); 2589 return; 2590 } 2591 removeStateForReusedUserIdIfNecessary(userId, userSerialNumber); 2592 initializeSyntheticPassword(userId); 2593 } 2594 } 2595 removeUser(@serIdInt int userId)2596 private void removeUser(@UserIdInt int userId) { 2597 synchronized (mUserCreationAndRemovalLock) { 2598 // During early boot, don't actually remove the LSS state yet, but rather automatically 2599 // delay it to later. We do this because deleting synthetic password protectors 2600 // requires the Weaver HAL if the device supports it, and some devices don't make Weaver 2601 // available until fairly late in the boot process. This logic ensures a consistent 2602 // flow across all devices, regardless of their Weaver implementation. 2603 if (!mThirdPartyAppsStarted) { 2604 Slogf.i(TAG, "Delaying locksettings state removal for user %d until third-party " + 2605 "apps are started", userId); 2606 if (mEarlyCreatedUsers.indexOfKey(userId) >= 0) { 2607 mEarlyCreatedUsers.delete(userId); 2608 } else { 2609 mEarlyRemovedUsers.put(userId, -1 /* unused */); 2610 } 2611 return; 2612 } 2613 Slogf.i(TAG, "Removing state for user %d", userId); 2614 removeUserState(userId); 2615 } 2616 } 2617 removeUserState(@serIdInt int userId)2618 private void removeUserState(@UserIdInt int userId) { 2619 removeBiometricsForUser(userId); 2620 mSpManager.removeUser(getGateKeeperService(), userId); 2621 mStrongAuth.removeUser(userId); 2622 2623 AndroidKeyStoreMaintenance.onUserRemoved(userId); 2624 mUnifiedProfilePasswordCache.removePassword(userId); 2625 2626 gateKeeperClearSecureUserId(userId); 2627 removeKeystoreProfileKey(userId); 2628 // Clean up storage last, so that removeStateForReusedUserIdIfNecessary() can assume that no 2629 // USER_SERIAL_NUMBER_KEY means user is fully removed. 2630 mStorage.removeUser(userId); 2631 } 2632 removeKeystoreProfileKey(int targetUserId)2633 private void removeKeystoreProfileKey(int targetUserId) { 2634 final String encryptAlias = PROFILE_KEY_NAME_ENCRYPT + targetUserId; 2635 final String decryptAlias = PROFILE_KEY_NAME_DECRYPT + targetUserId; 2636 try { 2637 if (mKeyStore.containsAlias(encryptAlias) || mKeyStore.containsAlias(decryptAlias)) { 2638 Slogf.i(TAG, "Removing keystore profile key for user %d", targetUserId); 2639 mKeyStore.deleteEntry(encryptAlias); 2640 mKeyStore.deleteEntry(decryptAlias); 2641 } 2642 } catch (KeyStoreException e) { 2643 // We have tried our best to remove the key. 2644 Slogf.e(TAG, e, "Error removing keystore profile key for user %d", targetUserId); 2645 } 2646 } 2647 2648 @Override registerStrongAuthTracker(IStrongAuthTracker tracker)2649 public void registerStrongAuthTracker(IStrongAuthTracker tracker) { 2650 checkPasswordReadPermission(); 2651 mStrongAuth.registerStrongAuthTracker(tracker); 2652 } 2653 2654 @Override unregisterStrongAuthTracker(IStrongAuthTracker tracker)2655 public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) { 2656 checkPasswordReadPermission(); 2657 mStrongAuth.unregisterStrongAuthTracker(tracker); 2658 } 2659 2660 @Override requireStrongAuth(int strongAuthReason, int userId)2661 public void requireStrongAuth(int strongAuthReason, int userId) { 2662 checkWritePermission(); 2663 mStrongAuth.requireStrongAuth(strongAuthReason, userId); 2664 } 2665 2666 @Override reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId)2667 public void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) { 2668 checkBiometricPermission(); 2669 mStrongAuth.reportSuccessfulBiometricUnlock(isStrongBiometric, userId); 2670 } 2671 2672 @Override scheduleNonStrongBiometricIdleTimeout(int userId)2673 public void scheduleNonStrongBiometricIdleTimeout(int userId) { 2674 checkBiometricPermission(); 2675 mStrongAuth.scheduleNonStrongBiometricIdleTimeout(userId); 2676 } 2677 2678 @Override userPresent(int userId)2679 public void userPresent(int userId) { 2680 checkWritePermission(); 2681 mStrongAuth.reportUnlock(userId); 2682 } 2683 2684 @Override getStrongAuthForUser(int userId)2685 public int getStrongAuthForUser(int userId) { 2686 checkPasswordReadPermission(); 2687 return mStrongAuthTracker.getStrongAuthForUser(userId); 2688 } 2689 isCallerShell()2690 private boolean isCallerShell() { 2691 final int callingUid = Binder.getCallingUid(); 2692 return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; 2693 } 2694 enforceShell()2695 private void enforceShell() { 2696 if (!isCallerShell()) { 2697 throw new SecurityException("Caller must be shell"); 2698 } 2699 } 2700 2701 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2702 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2703 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 2704 enforceShell(); 2705 final int callingPid = Binder.getCallingPid(); 2706 final int callingUid = Binder.getCallingUid(); 2707 2708 // Don't log arguments other than the first one (the command name), since they might contain 2709 // secrets that must not be written to the log. 2710 Slogf.i(TAG, "Executing shell command '%s'; callingPid=%d, callingUid=%d", 2711 ArrayUtils.isEmpty(args) ? "" : args[0], callingPid, callingUid); 2712 2713 // The original identity is an opaque integer. 2714 final long origId = Binder.clearCallingIdentity(); 2715 try { 2716 final LockSettingsShellCommand command = 2717 new LockSettingsShellCommand(new LockPatternUtils(mContext), mContext, 2718 callingPid, callingUid); 2719 command.exec(this, in, out, err, args, callback, resultReceiver); 2720 } finally { 2721 Binder.restoreCallingIdentity(origId); 2722 } 2723 } 2724 2725 @Override initRecoveryServiceWithSigFile(@onNull String rootCertificateAlias, @NonNull byte[] recoveryServiceCertFile, @NonNull byte[] recoveryServiceSigFile)2726 public void initRecoveryServiceWithSigFile(@NonNull String rootCertificateAlias, 2727 @NonNull byte[] recoveryServiceCertFile, @NonNull byte[] recoveryServiceSigFile) 2728 throws RemoteException { 2729 mRecoverableKeyStoreManager.initRecoveryServiceWithSigFile(rootCertificateAlias, 2730 recoveryServiceCertFile, recoveryServiceSigFile); 2731 } 2732 2733 @Override getKeyChainSnapshot()2734 public @NonNull KeyChainSnapshot getKeyChainSnapshot() throws RemoteException { 2735 return mRecoverableKeyStoreManager.getKeyChainSnapshot(); 2736 } 2737 2738 @Override setSnapshotCreatedPendingIntent(@ullable PendingIntent intent)2739 public void setSnapshotCreatedPendingIntent(@Nullable PendingIntent intent) 2740 throws RemoteException { 2741 mRecoverableKeyStoreManager.setSnapshotCreatedPendingIntent(intent); 2742 } 2743 2744 @Override setServerParams(byte[] serverParams)2745 public void setServerParams(byte[] serverParams) throws RemoteException { 2746 mRecoverableKeyStoreManager.setServerParams(serverParams); 2747 } 2748 2749 @Override setRecoveryStatus(String alias, int status)2750 public void setRecoveryStatus(String alias, int status) throws RemoteException { 2751 mRecoverableKeyStoreManager.setRecoveryStatus(alias, status); 2752 } 2753 2754 @Override getRecoveryStatus()2755 public @NonNull Map getRecoveryStatus() throws RemoteException { 2756 return mRecoverableKeyStoreManager.getRecoveryStatus(); 2757 } 2758 2759 @Override setRecoverySecretTypes(@onNull @eyChainProtectionParams.UserSecretType int[] secretTypes)2760 public void setRecoverySecretTypes(@NonNull @KeyChainProtectionParams.UserSecretType 2761 int[] secretTypes) throws RemoteException { 2762 mRecoverableKeyStoreManager.setRecoverySecretTypes(secretTypes); 2763 } 2764 2765 @Override getRecoverySecretTypes()2766 public @NonNull int[] getRecoverySecretTypes() throws RemoteException { 2767 return mRecoverableKeyStoreManager.getRecoverySecretTypes(); 2768 2769 } 2770 2771 @Override startRecoverySessionWithCertPath(@onNull String sessionId, @NonNull String rootCertificateAlias, @NonNull RecoveryCertPath verifierCertPath, @NonNull byte[] vaultParams, @NonNull byte[] vaultChallenge, @NonNull List<KeyChainProtectionParams> secrets)2772 public @NonNull byte[] startRecoverySessionWithCertPath(@NonNull String sessionId, 2773 @NonNull String rootCertificateAlias, @NonNull RecoveryCertPath verifierCertPath, 2774 @NonNull byte[] vaultParams, @NonNull byte[] vaultChallenge, 2775 @NonNull List<KeyChainProtectionParams> secrets) 2776 throws RemoteException { 2777 return mRecoverableKeyStoreManager.startRecoverySessionWithCertPath( 2778 sessionId, rootCertificateAlias, verifierCertPath, vaultParams, vaultChallenge, 2779 secrets); 2780 } 2781 2782 @Override recoverKeyChainSnapshot( @onNull String sessionId, @NonNull byte[] recoveryKeyBlob, @NonNull List<WrappedApplicationKey> applicationKeys)2783 public Map<String, String> recoverKeyChainSnapshot( 2784 @NonNull String sessionId, 2785 @NonNull byte[] recoveryKeyBlob, 2786 @NonNull List<WrappedApplicationKey> applicationKeys) throws RemoteException { 2787 return mRecoverableKeyStoreManager.recoverKeyChainSnapshot( 2788 sessionId, recoveryKeyBlob, applicationKeys); 2789 } 2790 2791 @Override closeSession(@onNull String sessionId)2792 public void closeSession(@NonNull String sessionId) throws RemoteException { 2793 mRecoverableKeyStoreManager.closeSession(sessionId); 2794 } 2795 2796 @Override removeKey(@onNull String alias)2797 public void removeKey(@NonNull String alias) throws RemoteException { 2798 mRecoverableKeyStoreManager.removeKey(alias); 2799 } 2800 2801 @Override generateKey(@onNull String alias)2802 public @Nullable String generateKey(@NonNull String alias) throws RemoteException { 2803 return mRecoverableKeyStoreManager.generateKey(alias); 2804 } 2805 2806 @Override generateKeyWithMetadata( @onNull String alias, @Nullable byte[] metadata)2807 public @Nullable String generateKeyWithMetadata( 2808 @NonNull String alias, @Nullable byte[] metadata) throws RemoteException { 2809 return mRecoverableKeyStoreManager.generateKeyWithMetadata(alias, metadata); 2810 } 2811 2812 @Override importKey(@onNull String alias, @NonNull byte[] keyBytes)2813 public @Nullable String importKey(@NonNull String alias, @NonNull byte[] keyBytes) 2814 throws RemoteException { 2815 return mRecoverableKeyStoreManager.importKey(alias, keyBytes); 2816 } 2817 2818 @Override importKeyWithMetadata(@onNull String alias, @NonNull byte[] keyBytes, @Nullable byte[] metadata)2819 public @Nullable String importKeyWithMetadata(@NonNull String alias, @NonNull byte[] keyBytes, 2820 @Nullable byte[] metadata) throws RemoteException { 2821 return mRecoverableKeyStoreManager.importKeyWithMetadata(alias, keyBytes, metadata); 2822 } 2823 2824 @Override getKey(@onNull String alias)2825 public @Nullable String getKey(@NonNull String alias) throws RemoteException { 2826 return mRecoverableKeyStoreManager.getKey(alias); 2827 } 2828 2829 /** 2830 * Starts a session to verify lock screen credentials provided by a remote device. 2831 */ 2832 @NonNull startRemoteLockscreenValidation()2833 public RemoteLockscreenValidationSession startRemoteLockscreenValidation() { 2834 return mRecoverableKeyStoreManager.startRemoteLockscreenValidation(this); 2835 } 2836 2837 /** 2838 * Verifies encrypted credentials guess from a remote device. 2839 */ 2840 @NonNull 2841 public RemoteLockscreenValidationResult validateRemoteLockscreen(@onNull byte[] encryptedCredential)2842 validateRemoteLockscreen(@NonNull byte[] encryptedCredential) { 2843 return mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential, this); 2844 } 2845 2846 private class GateKeeperDiedRecipient implements IBinder.DeathRecipient { 2847 @Override binderDied()2848 public void binderDied() { 2849 mGateKeeperService.asBinder().unlinkToDeath(this, 0); 2850 mGateKeeperService = null; 2851 } 2852 } 2853 getGateKeeperService()2854 private synchronized IGateKeeperService getGateKeeperService() { 2855 if (mGateKeeperService != null) { 2856 return mGateKeeperService; 2857 } 2858 2859 final IBinder service = ServiceManager.waitForService(Context.GATEKEEPER_SERVICE); 2860 if (service != null) { 2861 try { 2862 service.linkToDeath(new GateKeeperDiedRecipient(), 0); 2863 } catch (RemoteException e) { 2864 Slog.w(TAG, " Unable to register death recipient", e); 2865 } 2866 mGateKeeperService = IGateKeeperService.Stub.asInterface(service); 2867 return mGateKeeperService; 2868 } 2869 2870 Slog.e(TAG, "Unable to acquire GateKeeperService"); 2871 return null; 2872 } 2873 gateKeeperClearSecureUserId(int userId)2874 private void gateKeeperClearSecureUserId(int userId) { 2875 try { 2876 getGateKeeperService().clearSecureUserId(userId); 2877 } catch (RemoteException e) { 2878 Slog.w(TAG, "Failed to clear SID", e); 2879 } 2880 } 2881 onSyntheticPasswordCreated(@serIdInt int userId, SyntheticPassword sp)2882 private void onSyntheticPasswordCreated(@UserIdInt int userId, SyntheticPassword sp) { 2883 onSyntheticPasswordKnown(userId, sp, true); 2884 } 2885 onSyntheticPasswordUnlocked(@serIdInt int userId, SyntheticPassword sp)2886 private void onSyntheticPasswordUnlocked(@UserIdInt int userId, SyntheticPassword sp) { 2887 onSyntheticPasswordKnown(userId, sp, false); 2888 } 2889 onSyntheticPasswordKnown( @serIdInt int userId, SyntheticPassword sp, boolean justCreated)2890 private void onSyntheticPasswordKnown( 2891 @UserIdInt int userId, SyntheticPassword sp, boolean justCreated) { 2892 if (mInjector.isGsiRunning()) { 2893 Slog.w(TAG, "Running in GSI; skipping calls to AuthSecret and RebootEscrow"); 2894 return; 2895 } 2896 2897 mRebootEscrowManager.callToRebootEscrowIfNeeded( 2898 userId, sp.getVersion(), sp.getSyntheticPassword()); 2899 callToAuthSecretIfNeeded(userId, sp, justCreated); 2900 } 2901 2902 /** 2903 * Handles generation, storage, and sending of the vendor auth secret. Here we try to retrieve 2904 * the auth secret to send it to the auth secret HAL, generate a fresh secret if need be, store 2905 * it encrypted on disk so that the given user can unlock it in future, and stash it in memory 2906 * so that when future users are created they can also unlock it. 2907 * 2908 * <p>Called whenever the SP of a user is available, except in GSI. 2909 */ callToAuthSecretIfNeeded( @serIdInt int userId, SyntheticPassword sp, boolean justCreated)2910 private void callToAuthSecretIfNeeded( 2911 @UserIdInt int userId, SyntheticPassword sp, boolean justCreated) { 2912 if (mAuthSecretService == null) { 2913 // If there's no IAuthSecret service, we don't need to maintain a auth secret 2914 return; 2915 } 2916 // User may be partially created, so use the internal user manager interface 2917 final UserManagerInternal userManagerInternal = mInjector.getUserManagerInternal(); 2918 final UserInfo userInfo = userManagerInternal.getUserInfo(userId); 2919 if (userInfo == null) { 2920 // User may be partially deleted, skip this. 2921 return; 2922 } 2923 final byte[] authSecret; 2924 if (!mInjector.isHeadlessSystemUserMode()) { 2925 // On non-headless systems, the auth secret is derived from user 0's 2926 // SP, and only user 0 passes it to the HAL. 2927 if (userId != USER_SYSTEM) { 2928 return; 2929 } 2930 authSecret = sp.deriveVendorAuthSecret(); 2931 } else if (!mInjector.isMainUserPermanentAdmin() || !userInfo.isFull()) { 2932 // Only full users can receive or pass on the auth secret. 2933 // If there is no main permanent admin user, we don't try to create or send 2934 // an auth secret, since there may sometimes be no full users. 2935 return; 2936 } else if (justCreated) { 2937 if (userInfo.isMain()) { 2938 // The first user is just being created, so we create a new auth secret 2939 // at the same time. 2940 Slog.i(TAG, "Generating new vendor auth secret and storing for user: " + userId); 2941 authSecret = SecureRandomUtils.randomBytes(HEADLESS_VENDOR_AUTH_SECRET_LENGTH); 2942 // Store it in memory, for when new users are created. 2943 synchronized (mHeadlessAuthSecretLock) { 2944 mAuthSecret = authSecret; 2945 } 2946 } else { 2947 // A new user is being created. Another user should already have logged in at 2948 // this point, and therefore the auth secret should be stored in memory. 2949 synchronized (mHeadlessAuthSecretLock) { 2950 authSecret = mAuthSecret; 2951 } 2952 if (authSecret == null) { 2953 Slog.e(TAG, "Creating non-main user " + userId 2954 + " but vendor auth secret is not in memory"); 2955 return; 2956 } 2957 } 2958 // Store the auth secret encrypted using the user's SP (which was just created). 2959 mSpManager.writeVendorAuthSecret(authSecret, sp, userId); 2960 } else { 2961 // The user already exists, so the auth secret should be stored encrypted 2962 // with that user's SP. 2963 authSecret = mSpManager.readVendorAuthSecret(sp, userId); 2964 if (authSecret == null) { 2965 Slog.e(TAG, "Unable to read vendor auth secret for user: " + userId); 2966 return; 2967 } 2968 // Store it in memory, for when new users are created. 2969 synchronized (mHeadlessAuthSecretLock) { 2970 mAuthSecret = authSecret; 2971 } 2972 } 2973 Slog.i(TAG, "Sending vendor auth secret to IAuthSecret HAL as user: " + userId); 2974 try { 2975 mAuthSecretService.setPrimaryUserCredential(authSecret); 2976 } catch (RemoteException e) { 2977 Slog.w(TAG, "Failed to send vendor auth secret to IAuthSecret HAL", e); 2978 } 2979 } 2980 2981 /** 2982 * Creates the synthetic password (SP) for the given user, protects it with an empty LSKF, and 2983 * protects the user's CE storage key and Keystore super keys with keys derived from the SP. 2984 * 2985 * <p>This is called just once in the lifetime of the user: at user creation time (possibly 2986 * delayed until the time when Weaver is guaranteed to be available), or when upgrading from 2987 * Android 13 or earlier where users with no LSKF didn't necessarily have an SP. 2988 */ 2989 @VisibleForTesting initializeSyntheticPassword(int userId)2990 SyntheticPassword initializeSyntheticPassword(int userId) { 2991 synchronized (mSpManager) { 2992 Slogf.i(TAG, "Initializing synthetic password for user %d", userId); 2993 Preconditions.checkState(getCurrentLskfBasedProtectorId(userId) == 2994 SyntheticPasswordManager.NULL_PROTECTOR_ID, 2995 "Cannot reinitialize SP"); 2996 2997 final SyntheticPassword sp = mSpManager.newSyntheticPassword(userId); 2998 final long protectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), 2999 LockscreenCredential.createNone(), sp, userId); 3000 setCurrentLskfBasedProtectorId(protectorId, userId); 3001 setCeStorageProtection(userId, sp); 3002 initKeystoreSuperKeys(userId, sp, /* allowExisting= */ false); 3003 onSyntheticPasswordCreated(userId, sp); 3004 Slogf.i(TAG, "Successfully initialized synthetic password for user %d", userId); 3005 return sp; 3006 } 3007 } 3008 3009 @VisibleForTesting getCurrentLskfBasedProtectorId(int userId)3010 long getCurrentLskfBasedProtectorId(int userId) { 3011 return getLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, 3012 SyntheticPasswordManager.NULL_PROTECTOR_ID, userId); 3013 } 3014 setCurrentLskfBasedProtectorId(long newProtectorId, int userId)3015 private void setCurrentLskfBasedProtectorId(long newProtectorId, int userId) { 3016 final long oldProtectorId = getCurrentLskfBasedProtectorId(userId); 3017 setLong(CURRENT_LSKF_BASED_PROTECTOR_ID_KEY, newProtectorId, userId); 3018 setLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, oldProtectorId, userId); 3019 setLong(LSKF_LAST_CHANGED_TIME_KEY, System.currentTimeMillis(), userId); 3020 } 3021 3022 /** 3023 * Stores the gatekeeper password temporarily. 3024 * @param gatekeeperPassword unlocked upon successful Synthetic Password 3025 * @return non-zero handle to the gatekeeper password, which can be used for a set amount of 3026 * time. 3027 */ storeGatekeeperPasswordTemporarily(byte[] gatekeeperPassword)3028 private long storeGatekeeperPasswordTemporarily(byte[] gatekeeperPassword) { 3029 long handle = 0L; 3030 3031 synchronized (mGatekeeperPasswords) { 3032 while (handle == 0L || mGatekeeperPasswords.get(handle) != null) { 3033 handle = SecureRandomUtils.randomLong(); 3034 } 3035 mGatekeeperPasswords.put(handle, gatekeeperPassword); 3036 } 3037 3038 final long finalHandle = handle; 3039 mHandler.postDelayed(() -> { 3040 synchronized (mGatekeeperPasswords) { 3041 if (mGatekeeperPasswords.get(finalHandle) != null) { 3042 Slogf.d(TAG, "Cached Gatekeeper password with handle %016x has expired", 3043 finalHandle); 3044 mGatekeeperPasswords.remove(finalHandle); 3045 } 3046 } 3047 }, GK_PW_HANDLE_STORE_DURATION_MS); 3048 3049 return handle; 3050 } 3051 onCredentialVerified(SyntheticPassword sp, @Nullable PasswordMetrics metrics, int userId)3052 private void onCredentialVerified(SyntheticPassword sp, @Nullable PasswordMetrics metrics, 3053 int userId) { 3054 3055 if (metrics != null) { 3056 synchronized (this) { 3057 mUserPasswordMetrics.put(userId, metrics); 3058 } 3059 } 3060 3061 unlockKeystore(userId, sp); 3062 3063 unlockCeStorage(userId, sp); 3064 3065 unlockUser(userId); 3066 3067 activateEscrowTokens(sp, userId); 3068 3069 if (isCredentialShareableWithParent(userId)) { 3070 if (getSeparateProfileChallengeEnabledInternal(userId)) { 3071 setDeviceUnlockedForUser(userId); 3072 } else { 3073 // Here only clear StrongAuthFlags for a profile that has a unified challenge. 3074 // StrongAuth for a profile with a separate challenge is handled differently and 3075 // is cleared after the user successfully confirms the separate challenge to enter 3076 // the profile. StrongAuth for the full user (e.g. userId 0) is also handled 3077 // separately by Keyguard. 3078 mStrongAuth.reportUnlock(userId); 3079 } 3080 } 3081 3082 mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); 3083 3084 onSyntheticPasswordUnlocked(userId, sp); 3085 } 3086 setDeviceUnlockedForUser(int userId)3087 private void setDeviceUnlockedForUser(int userId) { 3088 final TrustManager trustManager = mContext.getSystemService(TrustManager.class); 3089 trustManager.setDeviceLockedForUser(userId, false); 3090 } 3091 3092 /** 3093 * Changes the user's LSKF by creating an LSKF-based protector that uses the new LSKF (which may 3094 * be empty) and replacing the old LSKF-based protector with it. The SP itself is not changed. 3095 * <p> 3096 * Also maintains the invariants described in {@link SyntheticPasswordManager} by enrolling / 3097 * deleting the synthetic password into Gatekeeper as the LSKF is set / cleared, and asking 3098 * Keystore to delete the user's auth-bound keys when the LSKF is cleared. 3099 */ 3100 @GuardedBy("mSpManager") setLockCredentialWithSpLocked(LockscreenCredential credential, SyntheticPassword sp, int userId)3101 private long setLockCredentialWithSpLocked(LockscreenCredential credential, 3102 SyntheticPassword sp, int userId) { 3103 Slogf.i(TAG, "Changing lockscreen credential of user %d; newCredentialType=%s\n", 3104 userId, LockPatternUtils.credentialTypeToString(credential.getType())); 3105 final int savedCredentialType = getCredentialTypeInternal(userId); 3106 final long oldProtectorId = getCurrentLskfBasedProtectorId(userId); 3107 final long newProtectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), 3108 credential, sp, userId); 3109 final Map<Integer, LockscreenCredential> profilePasswords; 3110 if (!credential.isNone()) { 3111 // not needed by synchronizeUnifiedChallengeForProfiles() 3112 profilePasswords = null; 3113 3114 if (!mSpManager.hasSidForUser(userId)) { 3115 mSpManager.newSidForUser(getGateKeeperService(), sp, userId); 3116 mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId); 3117 } 3118 } else { 3119 // Cache all profile password if they use unified challenge. This will later be used to 3120 // clear the profile's password in synchronizeUnifiedChallengeForProfiles(). 3121 profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId); 3122 3123 mSpManager.clearSidForUser(userId); 3124 gateKeeperClearSecureUserId(userId); 3125 unlockCeStorage(userId, sp); 3126 unlockKeystore(userId, sp); 3127 AndroidKeyStoreMaintenance.onUserLskfRemoved(userId); 3128 removeBiometricsForUser(userId); 3129 } 3130 setCurrentLskfBasedProtectorId(newProtectorId, userId); 3131 LockPatternUtils.invalidateCredentialTypeCache(); 3132 synchronizeUnifiedChallengeForProfiles(userId, profilePasswords); 3133 3134 setUserPasswordMetrics(credential, userId); 3135 mUnifiedProfilePasswordCache.removePassword(userId); 3136 if (savedCredentialType != CREDENTIAL_TYPE_NONE) { 3137 mSpManager.destroyAllWeakTokenBasedProtectors(userId); 3138 } 3139 3140 if (profilePasswords != null) { 3141 for (Map.Entry<Integer, LockscreenCredential> entry : profilePasswords.entrySet()) { 3142 entry.getValue().zeroize(); 3143 } 3144 } 3145 mSpManager.destroyLskfBasedProtector(oldProtectorId, userId); 3146 Slogf.i(TAG, "Successfully changed lockscreen credential of user %d", userId); 3147 return newProtectorId; 3148 } 3149 sendMainUserCredentialChangedNotificationIfNeeded(int userId)3150 private void sendMainUserCredentialChangedNotificationIfNeeded(int userId) { 3151 if (!android.security.Flags.frpEnforcement()) { 3152 return; 3153 } 3154 3155 if (userId != mInjector.getUserManagerInternal().getMainUserId()) { 3156 return; 3157 } 3158 3159 sendBroadcast(new Intent(ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED), 3160 UserHandle.of(userId), CONFIGURE_FACTORY_RESET_PROTECTION); 3161 } 3162 3163 @VisibleForTesting sendBroadcast(Intent intent, UserHandle userHandle, String permission)3164 void sendBroadcast(Intent intent, UserHandle userHandle, String permission) { 3165 mContext.sendBroadcastAsUser(intent, userHandle, permission, /* options */ null); 3166 } 3167 removeBiometricsForUser(int userId)3168 private void removeBiometricsForUser(int userId) { 3169 removeAllFingerprintForUser(userId); 3170 removeAllFaceForUser(userId); 3171 } 3172 removeAllFingerprintForUser(final int userId)3173 private void removeAllFingerprintForUser(final int userId) { 3174 FingerprintManager mFingerprintManager = mInjector.getFingerprintManager(); 3175 if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) { 3176 if (mFingerprintManager.hasEnrolledFingerprints(userId)) { 3177 final CountDownLatch latch = new CountDownLatch(1); 3178 mFingerprintManager.removeAll(userId, fingerprintManagerRemovalCallback(latch)); 3179 try { 3180 latch.await(10000, TimeUnit.MILLISECONDS); 3181 } catch (InterruptedException e) { 3182 Slog.e(TAG, "Latch interrupted when removing fingerprint", e); 3183 } 3184 } 3185 } 3186 } 3187 removeAllFaceForUser(final int userId)3188 private void removeAllFaceForUser(final int userId) { 3189 FaceManager mFaceManager = mInjector.getFaceManager(); 3190 if (mFaceManager != null && mFaceManager.isHardwareDetected()) { 3191 if (mFaceManager.hasEnrolledTemplates(userId)) { 3192 final CountDownLatch latch = new CountDownLatch(1); 3193 mFaceManager.removeAll(userId, faceManagerRemovalCallback(latch)); 3194 try { 3195 latch.await(10000, TimeUnit.MILLISECONDS); 3196 } catch (InterruptedException e) { 3197 Slog.e(TAG, "Latch interrupted when removing face", e); 3198 } 3199 } 3200 } 3201 } 3202 fingerprintManagerRemovalCallback( CountDownLatch latch)3203 private FingerprintManager.RemovalCallback fingerprintManagerRemovalCallback( 3204 CountDownLatch latch) { 3205 return new FingerprintManager.RemovalCallback() { 3206 @Override 3207 public void onRemovalError(@Nullable Fingerprint fp, int errMsgId, CharSequence err) { 3208 Slog.e(TAG, "Unable to remove fingerprint, error: " + err); 3209 latch.countDown(); 3210 } 3211 3212 @Override 3213 public void onRemovalSucceeded(Fingerprint fp, int remaining) { 3214 if (remaining == 0) { 3215 latch.countDown(); 3216 } 3217 } 3218 }; 3219 } 3220 3221 private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) { 3222 return new FaceManager.RemovalCallback() { 3223 @Override 3224 public void onRemovalError(@Nullable Face face, int errMsgId, CharSequence err) { 3225 Slog.e(TAG, "Unable to remove face, error: " + err); 3226 latch.countDown(); 3227 } 3228 3229 @Override 3230 public void onRemovalSucceeded(Face face, int remaining) { 3231 if (remaining == 0) { 3232 latch.countDown(); 3233 } 3234 } 3235 }; 3236 } 3237 3238 /** 3239 * Returns a fixed pseudorandom byte string derived from the user's synthetic password. 3240 * This is used to salt the password history hash to protect the hash against offline 3241 * bruteforcing, since rederiving this value requires a successful authentication. 3242 * If user is a profile with unified challenge, currentCredential is ignored. 3243 */ 3244 @Override 3245 public byte[] getHashFactor(LockscreenCredential currentCredential, int userId) { 3246 checkPasswordReadPermission(); 3247 try { 3248 Slogf.d(TAG, "Getting password history hash factor for user %d", userId); 3249 if (isProfileWithUnifiedLock(userId)) { 3250 try { 3251 currentCredential = getDecryptedPasswordForTiedProfile(userId); 3252 } catch (Exception e) { 3253 Slog.e(TAG, "Failed to get unified profile password", e); 3254 return null; 3255 } 3256 } 3257 synchronized (mSpManager) { 3258 long protectorId = getCurrentLskfBasedProtectorId(userId); 3259 AuthenticationResult auth = mSpManager.unlockLskfBasedProtector( 3260 getGateKeeperService(), protectorId, currentCredential, userId, null); 3261 if (auth.syntheticPassword == null) { 3262 Slog.w(TAG, "Current credential is incorrect"); 3263 return null; 3264 } 3265 return auth.syntheticPassword.derivePasswordHashFactor(); 3266 } 3267 } finally { 3268 scheduleGc(); 3269 } 3270 } 3271 3272 private long addEscrowToken(@NonNull byte[] token, @TokenType int type, int userId, 3273 @NonNull EscrowTokenStateChangeCallback callback) { 3274 Slogf.i(TAG, "Adding escrow token for user %d", userId); 3275 synchronized (mSpManager) { 3276 // If the user has no LSKF, then the token can be activated immediately. Otherwise, the 3277 // token can't be activated until the SP is unlocked by another protector (normally the 3278 // LSKF-based one). 3279 SyntheticPassword sp = null; 3280 if (!isUserSecure(userId)) { 3281 long protectorId = getCurrentLskfBasedProtectorId(userId); 3282 sp = mSpManager.unlockLskfBasedProtector(getGateKeeperService(), protectorId, 3283 LockscreenCredential.createNone(), userId, null).syntheticPassword; 3284 } 3285 disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); 3286 if (!mSpManager.hasEscrowData(userId)) { 3287 throw new SecurityException("Escrow token is disabled on the current user"); 3288 } 3289 long handle = mSpManager.addPendingToken(token, type, userId, callback); 3290 if (sp != null) { 3291 // Activate the token immediately 3292 Slogf.i(TAG, "Immediately activating escrow token %016x", handle); 3293 mSpManager.createTokenBasedProtector(handle, sp, userId); 3294 } else { 3295 Slogf.i(TAG, "Escrow token %016x will be activated when user is unlocked", handle); 3296 } 3297 return handle; 3298 } 3299 } 3300 3301 private void activateEscrowTokens(SyntheticPassword sp, int userId) { 3302 synchronized (mSpManager) { 3303 disableEscrowTokenOnNonManagedDevicesIfNeeded(userId); 3304 for (long handle : mSpManager.getPendingTokensForUser(userId)) { 3305 Slogf.i(TAG, "Activating escrow token %016x for user %d", handle, userId); 3306 mSpManager.createTokenBasedProtector(handle, sp, userId); 3307 } 3308 } 3309 } 3310 3311 private boolean isEscrowTokenActive(long handle, int userId) { 3312 synchronized (mSpManager) { 3313 return mSpManager.protectorExists(handle, userId); 3314 } 3315 } 3316 3317 @Override 3318 public boolean hasPendingEscrowToken(int userId) { 3319 checkPasswordReadPermission(); 3320 synchronized (mSpManager) { 3321 return !mSpManager.getPendingTokensForUser(userId).isEmpty(); 3322 } 3323 } 3324 3325 private boolean removeEscrowToken(long handle, int userId) { 3326 synchronized (mSpManager) { 3327 if (handle == getCurrentLskfBasedProtectorId(userId)) { 3328 Slog.w(TAG, "Escrow token handle equals LSKF-based protector ID"); 3329 return false; 3330 } 3331 if (mSpManager.removePendingToken(handle, userId)) { 3332 return true; 3333 } 3334 if (mSpManager.protectorExists(handle, userId)) { 3335 mSpManager.destroyTokenBasedProtector(handle, userId); 3336 return true; 3337 } else { 3338 return false; 3339 } 3340 } 3341 } 3342 3343 private boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, 3344 byte[] token, int userId) { 3345 boolean result; 3346 credential.validateBasicRequirements(); 3347 synchronized (mSpManager) { 3348 if (!mSpManager.hasEscrowData(userId)) { 3349 throw new SecurityException("Escrow token is disabled on the current user"); 3350 } 3351 if (!isEscrowTokenActive(tokenHandle, userId)) { 3352 Slog.e(TAG, "Unknown or unactivated token: " + Long.toHexString(tokenHandle)); 3353 return false; 3354 } 3355 result = setLockCredentialWithTokenInternalLocked( 3356 credential, tokenHandle, token, userId); 3357 } 3358 if (result) { 3359 synchronized (mSeparateChallengeLock) { 3360 setSeparateProfileChallengeEnabledLocked(userId, true, /* unused */ null); 3361 } 3362 if (credential.isNone()) { 3363 // If clearing credential, unlock the user manually in order to progress user start 3364 // Call unlockUser() on a handler thread so no lock is held (either by LSS or by 3365 // the caller like DPMS), otherwise it can lead to deadlock. 3366 mHandler.post(() -> unlockUser(userId)); 3367 } 3368 notifyPasswordChanged(credential, userId); 3369 notifySeparateProfileChallengeChanged(userId); 3370 } 3371 return result; 3372 } 3373 3374 @GuardedBy("mSpManager") 3375 private boolean setLockCredentialWithTokenInternalLocked(LockscreenCredential credential, 3376 long tokenHandle, byte[] token, int userId) { 3377 Slogf.i(TAG, "Resetting lockscreen credential of user %d using escrow token %016x", 3378 userId, tokenHandle); 3379 final AuthenticationResult result; 3380 result = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle, token, 3381 userId); 3382 if (result.syntheticPassword == null) { 3383 Slog.w(TAG, "Invalid escrow token supplied"); 3384 return false; 3385 } 3386 if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { 3387 // Most likely, an untrusted credential reset happened in the past which 3388 // changed the synthetic password 3389 Slog.e(TAG, "Obsolete token: synthetic password decrypted but it fails GK " 3390 + "verification."); 3391 return false; 3392 } 3393 onSyntheticPasswordUnlocked(userId, result.syntheticPassword); 3394 setLockCredentialWithSpLocked(credential, result.syntheticPassword, userId); 3395 return true; 3396 } 3397 3398 private boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { 3399 AuthenticationResult authResult; 3400 synchronized (mSpManager) { 3401 Slogf.i(TAG, "Unlocking user %d using escrow token %016x", userId, tokenHandle); 3402 if (!mSpManager.hasEscrowData(userId)) { 3403 Slogf.w(TAG, "Escrow token support is disabled on user %d", userId); 3404 return false; 3405 } 3406 authResult = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle, 3407 token, userId); 3408 if (authResult.syntheticPassword == null) { 3409 Slog.w(TAG, "Invalid escrow token supplied"); 3410 return false; 3411 } 3412 } 3413 3414 Slogf.i(TAG, "Unlocked synthetic password for user %d using escrow token", userId); 3415 onCredentialVerified(authResult.syntheticPassword, 3416 loadPasswordMetrics(authResult.syntheticPassword, userId), userId); 3417 return true; 3418 } 3419 3420 @Override 3421 public boolean tryUnlockWithCachedUnifiedChallenge(int userId) { 3422 checkPasswordReadPermission(); 3423 try (LockscreenCredential cred = mUnifiedProfilePasswordCache.retrievePassword(userId)) { 3424 if (cred == null) { 3425 return false; 3426 } 3427 return doVerifyCredential(cred, userId, null /* progressCallback */, 0 /* flags */) 3428 .getResponseCode() == VerifyCredentialResponse.RESPONSE_OK; 3429 } 3430 } 3431 3432 @Override 3433 public void removeCachedUnifiedChallenge(int userId) { 3434 checkWritePermission(); 3435 mUnifiedProfilePasswordCache.removePassword(userId); 3436 } 3437 3438 static String timestampToString(long timestamp) { 3439 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timestamp)); 3440 } 3441 3442 @Override 3443 protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 3444 if (!DumpUtils.checkDumpPermission(mContext, TAG, printWriter)) return; 3445 3446 final long identity = Binder.clearCallingIdentity(); 3447 try { 3448 dumpInternal(printWriter); 3449 } finally { 3450 Binder.restoreCallingIdentity(identity); 3451 } 3452 } 3453 3454 private void dumpInternal(PrintWriter printWriter) { 3455 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 3456 3457 pw.println("Current lock settings service state:"); 3458 pw.println(); 3459 3460 pw.println("User State:"); 3461 pw.increaseIndent(); 3462 List<UserInfo> users = mUserManager.getUsers(); 3463 for (int user = 0; user < users.size(); user++) { 3464 final int userId = users.get(user).id; 3465 pw.println("User " + userId); 3466 pw.increaseIndent(); 3467 synchronized (mSpManager) { 3468 pw.println(TextUtils.formatSimple("LSKF-based SP protector ID: %016x", 3469 getCurrentLskfBasedProtectorId(userId))); 3470 pw.println(TextUtils.formatSimple( 3471 "LSKF last changed: %s (previous protector: %016x)", 3472 timestampToString(getLong(LSKF_LAST_CHANGED_TIME_KEY, 0, userId)), 3473 getLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId))); 3474 } 3475 try { 3476 pw.println(TextUtils.formatSimple("SID: %016x", 3477 getGateKeeperService().getSecureUserId(userId))); 3478 } catch (RemoteException e) { 3479 // ignore. 3480 } 3481 // It's OK to dump the credential type since anyone with physical access can just 3482 // observe it from the keyguard directly. 3483 pw.println("Quality: " + getKeyguardStoredQuality(userId)); 3484 final int credentialType = getCredentialTypeInternal(userId); 3485 pw.println("CredentialType: " 3486 + LockPatternUtils.credentialTypeToString(credentialType)); 3487 if (credentialType == CREDENTIAL_TYPE_NONE) { 3488 pw.println("IsLockScreenDisabled: " 3489 + getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, userId)); 3490 } 3491 pw.println("SeparateChallenge: " + getSeparateProfileChallengeEnabledInternal(userId)); 3492 pw.println(TextUtils.formatSimple("Metrics: %s", 3493 getUserPasswordMetrics(userId) != null ? "known" : "unknown")); 3494 pw.decreaseIndent(); 3495 } 3496 pw.println(); 3497 pw.decreaseIndent(); 3498 3499 pw.println("Keys in namespace:"); 3500 pw.increaseIndent(); 3501 dumpKeystoreKeys(pw); 3502 pw.println(); 3503 pw.decreaseIndent(); 3504 3505 pw.println("Storage:"); 3506 pw.increaseIndent(); 3507 mStorage.dump(pw); 3508 pw.println(); 3509 pw.decreaseIndent(); 3510 3511 pw.println("StrongAuth:"); 3512 pw.increaseIndent(); 3513 mStrongAuth.dump(pw); 3514 pw.println(); 3515 pw.decreaseIndent(); 3516 3517 pw.println("RebootEscrow:"); 3518 pw.increaseIndent(); 3519 mRebootEscrowManager.dump(pw); 3520 pw.println(); 3521 pw.decreaseIndent(); 3522 3523 pw.println("PasswordHandleCount: " + mGatekeeperPasswords.size()); 3524 synchronized (mUserCreationAndRemovalLock) { 3525 pw.println("ThirdPartyAppsStarted: " + mThirdPartyAppsStarted); 3526 } 3527 } 3528 3529 private void dumpKeystoreKeys(IndentingPrintWriter pw) { 3530 try { 3531 final Enumeration<String> aliases = mKeyStore.aliases(); 3532 while (aliases.hasMoreElements()) { 3533 pw.println(aliases.nextElement()); 3534 } 3535 } catch (KeyStoreException e) { 3536 pw.println("Unable to get keys: " + e.toString()); 3537 Slog.d(TAG, "Dump error", e); 3538 } 3539 } 3540 3541 /** 3542 * Cryptographically disable escrow token support for the current user, if the user is not 3543 * managed (either user has a profile owner, or if device is managed). Do not disable 3544 * if we are running an automotive build. 3545 */ 3546 private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) { 3547 3548 if (!mSpManager.hasAnyEscrowData(userId)) { 3549 return; 3550 } 3551 3552 // TODO(b/258213147): Remove 3553 final long identity = Binder.clearCallingIdentity(); 3554 try { 3555 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER, 3556 DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG, 3557 DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) { 3558 3559 if (mInjector.getDeviceStateCache().isUserOrganizationManaged(userId)) { 3560 Slog.i(TAG, "Organization managed users can have escrow token"); 3561 return; 3562 } 3563 } else { 3564 final UserManagerInternal userManagerInternal = mInjector.getUserManagerInternal(); 3565 3566 // Managed profile should have escrow enabled 3567 if (userManagerInternal.isUserManaged(userId)) { 3568 Slog.i(TAG, "Managed profile can have escrow token"); 3569 return; 3570 } 3571 3572 // Devices with Device Owner should have escrow enabled on all users. 3573 if (userManagerInternal.isDeviceManaged()) { 3574 Slog.i(TAG, "Corp-owned device can have escrow token"); 3575 return; 3576 } 3577 } 3578 } finally { 3579 Binder.restoreCallingIdentity(identity); 3580 } 3581 3582 // If the device is yet to be provisioned (still in SUW), there is still 3583 // a chance that Device Owner will be set on the device later, so postpone 3584 // disabling escrow token for now. 3585 if (!mInjector.getDeviceStateCache().isDeviceProvisioned()) { 3586 Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned"); 3587 return; 3588 } 3589 3590 // Escrow tokens are enabled on automotive builds. 3591 if (RoSystemFeatures.hasFeatureAutomotive(mContext)) { 3592 return; 3593 } 3594 3595 UserInfo userInfo = mInjector.getUserManagerInternal().getUserInfo(userId); 3596 if (userInfo != null && userInfo.isForTesting()) { 3597 Slog.i(TAG, "Keeping escrow data for test-only user"); 3598 return; 3599 } 3600 3601 // Disable escrow token permanently on all other device/user types. 3602 Slogf.i(TAG, "Permanently disabling support for escrow tokens on user %d", userId); 3603 mSpManager.destroyEscrowData(userId); 3604 } 3605 3606 /** 3607 * Schedules garbage collection to sanitize lockscreen credential remnants in memory. 3608 * 3609 * One source of leftover lockscreen credentials is the unmarshalled binder method arguments. 3610 * Since this method will be called within the binder implementation method, a small delay is 3611 * added before the GC operation to allow the enclosing binder proxy code to complete and 3612 * release references to the argument. 3613 */ 3614 private void scheduleGc() { 3615 // Cancel any existing GC request first, so that GC requests don't pile up if lockscreen 3616 // credential operations are happening very quickly, e.g. as sometimes happens during tests. 3617 // 3618 // This delays the already-requested GC, but that is fine in practice where lockscreen 3619 // operations don't happen very quickly. And the precise time that the sanitization happens 3620 // isn't very important; doing it within a minute can be fine, for example. 3621 mHandler.removeCallbacksAndMessages(mGcWorkToken); 3622 3623 mHandler.postDelayed(() -> { 3624 System.gc(); 3625 System.runFinalization(); 3626 System.gc(); 3627 }, mGcWorkToken, 2000); 3628 } 3629 3630 private class DeviceProvisionedObserver extends ContentObserver { 3631 private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor( 3632 Settings.Global.DEVICE_PROVISIONED); 3633 3634 private boolean mRegistered; 3635 3636 public DeviceProvisionedObserver() { 3637 super(null); 3638 } 3639 3640 @Override 3641 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 3642 if (mDeviceProvisionedUri.equals(uri)) { 3643 updateRegistration(); 3644 3645 if (isProvisioned()) { 3646 Slog.i(TAG, "Reporting device setup complete to IGateKeeperService"); 3647 reportDeviceSetupComplete(); 3648 clearFrpCredentialIfOwnerNotSecure(); 3649 } 3650 } 3651 } 3652 3653 public void onSystemReady() { 3654 if (frpCredentialEnabled(mContext)) { 3655 updateRegistration(); 3656 } else { 3657 // If we don't intend to use frpCredentials and we're not provisioned yet, send 3658 // deviceSetupComplete immediately, so gatekeeper can discard any lingering 3659 // credentials immediately. 3660 if (!isProvisioned()) { 3661 Slog.i(TAG, "FRP credential disabled, reporting device setup complete " 3662 + "to Gatekeeper immediately"); 3663 reportDeviceSetupComplete(); 3664 } 3665 } 3666 } 3667 3668 private void reportDeviceSetupComplete() { 3669 try { 3670 getGateKeeperService().reportDeviceSetupComplete(); 3671 } catch (RemoteException e) { 3672 Slog.e(TAG, "Failure reporting to IGateKeeperService", e); 3673 } 3674 } 3675 3676 /** 3677 * Clears the FRP credential if the user that controls it does not have a secure 3678 * lockscreen. 3679 */ 3680 private void clearFrpCredentialIfOwnerNotSecure() { 3681 List<UserInfo> users = mUserManager.getUsers(); 3682 for (UserInfo user : users) { 3683 if (userOwnsFrpCredential(mContext, user)) { 3684 if (!isUserSecure(user.id)) { 3685 Slogf.d(TAG, "Clearing FRP credential tied to user %d", user.id); 3686 mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, user.id, 3687 0, null); 3688 } 3689 return; 3690 } 3691 } 3692 } 3693 3694 private void updateRegistration() { 3695 boolean register = !isProvisioned(); 3696 if (register == mRegistered) { 3697 return; 3698 } 3699 if (register) { 3700 mContext.getContentResolver().registerContentObserver(mDeviceProvisionedUri, 3701 false, this); 3702 } else { 3703 mContext.getContentResolver().unregisterContentObserver(this); 3704 } 3705 mRegistered = register; 3706 } 3707 3708 private boolean isProvisioned() { 3709 return Settings.Global.getInt(mContext.getContentResolver(), 3710 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 3711 } 3712 } 3713 3714 private final class LocalService extends LockSettingsInternal { 3715 3716 @Override 3717 public void onThirdPartyAppsStarted() { 3718 LockSettingsService.this.onThirdPartyAppsStarted(); 3719 } 3720 3721 @Override 3722 public void createNewUser(@UserIdInt int userId, int userSerialNumber) { 3723 LockSettingsService.this.createNewUser(userId, userSerialNumber); 3724 } 3725 3726 @Override 3727 public void removeUser(@UserIdInt int userId) { 3728 LockSettingsService.this.removeUser(userId); 3729 } 3730 3731 @Override 3732 public long addEscrowToken(byte[] token, int userId, 3733 EscrowTokenStateChangeCallback callback) { 3734 return LockSettingsService.this.addEscrowToken(token, TOKEN_TYPE_STRONG, userId, 3735 callback); 3736 } 3737 3738 @Override 3739 public boolean removeEscrowToken(long handle, int userId) { 3740 return LockSettingsService.this.removeEscrowToken(handle, userId); 3741 } 3742 3743 @Override 3744 public boolean isEscrowTokenActive(long handle, int userId) { 3745 return LockSettingsService.this.isEscrowTokenActive(handle, userId); 3746 } 3747 3748 @Override 3749 public boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, 3750 byte[] token, int userId) { 3751 if (!mHasSecureLockScreen 3752 && credential != null && credential.getType() != CREDENTIAL_TYPE_NONE) { 3753 throw new UnsupportedOperationException( 3754 "This operation requires secure lock screen feature."); 3755 } 3756 if (!LockSettingsService.this.setLockCredentialWithToken( 3757 credential, tokenHandle, token, userId)) { 3758 return false; 3759 } 3760 onPostPasswordChanged(credential, userId); 3761 return true; 3762 } 3763 3764 @Override 3765 public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { 3766 return LockSettingsService.this.unlockUserWithToken(tokenHandle, token, userId); 3767 } 3768 3769 @Override 3770 public PasswordMetrics getUserPasswordMetrics(int userHandle) { 3771 final long identity = Binder.clearCallingIdentity(); 3772 try { 3773 if (isProfileWithUnifiedLock(userHandle)) { 3774 // A managed/clone profile with unified challenge is supposed to be protected by 3775 // the parent lockscreen, so asking for its password metrics is not really 3776 // useful, as this method would just return the metrics of the random profile 3777 // password 3778 Slog.w(TAG, "Querying password metrics for unified challenge profile: " 3779 + userHandle); 3780 } 3781 return LockSettingsService.this.getUserPasswordMetrics(userHandle); 3782 } finally { 3783 Binder.restoreCallingIdentity(identity); 3784 } 3785 } 3786 3787 @Override 3788 public boolean prepareRebootEscrow() { 3789 if (!mRebootEscrowManager.prepareRebootEscrow()) { 3790 return false; 3791 } 3792 mStrongAuth.requireStrongAuth(STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE, USER_ALL); 3793 return true; 3794 } 3795 3796 @Override 3797 public void setRebootEscrowListener(RebootEscrowListener listener) { 3798 mRebootEscrowManager.setRebootEscrowListener(listener); 3799 } 3800 3801 @Override 3802 public boolean clearRebootEscrow() { 3803 if (!mRebootEscrowManager.clearRebootEscrow()) { 3804 return false; 3805 } 3806 mStrongAuth.noLongerRequireStrongAuth(STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE, 3807 USER_ALL); 3808 return true; 3809 } 3810 3811 @Override 3812 public @ArmRebootEscrowErrorCode int armRebootEscrow() { 3813 return mRebootEscrowManager.armRebootEscrowIfNeeded(); 3814 } 3815 3816 @Override 3817 public void refreshStrongAuthTimeout(int userId) { 3818 mStrongAuth.refreshStrongAuthTimeout(userId); 3819 } 3820 3821 @Override 3822 public void registerLockSettingsStateListener(@NonNull LockSettingsStateListener listener) { 3823 Objects.requireNonNull(listener, "listener cannot be null"); 3824 mLockSettingsStateListeners.add(listener); 3825 } 3826 3827 @Override 3828 public void unregisterLockSettingsStateListener( 3829 @NonNull LockSettingsStateListener listener) { 3830 mLockSettingsStateListeners.remove(listener); 3831 } 3832 } 3833 3834 private class RebootEscrowCallbacks implements RebootEscrowManager.Callbacks { 3835 @Override 3836 public boolean isUserSecure(int userId) { 3837 return LockSettingsService.this.isUserSecure(userId); 3838 } 3839 3840 @Override 3841 public void onRebootEscrowRestored(byte spVersion, byte[] rawSyntheticPassword, 3842 int userId) { 3843 SyntheticPasswordManager.SyntheticPassword 3844 sp = new SyntheticPasswordManager.SyntheticPassword(spVersion); 3845 sp.recreateDirectly(rawSyntheticPassword); 3846 synchronized (mSpManager) { 3847 mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId); 3848 } 3849 Slogf.i(TAG, "Restored synthetic password for user %d using reboot escrow", userId); 3850 onCredentialVerified(sp, loadPasswordMetrics(sp, userId), userId); 3851 } 3852 } 3853 } 3854