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