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