From 4459123d4932a2f4091115a5141d2ca63747ca09 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Tue, 27 Apr 2021 08:31:15 -0700 Subject: [PATCH 1/2] Use UserHandle.myUserId() to look up user BiometricManager runs in the app, not in system server, so use the appropriate call to look up the current user. Test: aosp/1686345 Bug: 163866361 Change-Id: I10c1ddacf14bd6b77ecfc1cb8235c42b8a7fbcfe --- core/java/android/hardware/biometrics/BiometricManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index a778c246ce1b6..34f43065ee205 100644 --- a/core/java/android/hardware/biometrics/BiometricManager.java +++ b/core/java/android/hardware/biometrics/BiometricManager.java @@ -335,7 +335,7 @@ public class BiometricManager { * @hide */ public long[] getAuthenticatorIds() { - return getAuthenticatorIds(UserHandle.getCallingUserId()); + return getAuthenticatorIds(UserHandle.myUserId()); } /** From 336b5db80970f5539ced3cd2f0b73c8b7a6aa116 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Thu, 8 Apr 2021 17:33:31 -0700 Subject: [PATCH 2/2] Tell keystore which SIDs can unlock this user If biometric unlock is enabled, we tell keystore at lock time so that a key can be set up in KM which unlocks UNLOCKED_DEVICE_REQUIRED keys based on auth tokens carrying those SIDs. This also has the effect that if there is no biometric unlock, UNLOCKED_DEVICE_REQUIRED keys have full cryptographic protection, per NIAP requirements. Test: aosp/1686345 Bug: 163866361 Change-Id: Ia4d01faa998c76b2b33ad3520730466ac59e6d8d --- .../java/android/security/Authorization.java | 9 +++++--- .../locksettings/LockSettingsService.java | 2 +- .../server/trust/TrustManagerService.java | 22 +++++++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java index bd72d45297c11..00219e7f28ac9 100644 --- a/keystore/java/android/security/Authorization.java +++ b/keystore/java/android/security/Authorization.java @@ -74,16 +74,19 @@ public class Authorization { * @param locked - whether it is a lock (true) or unlock (false) event * @param syntheticPassword - if it is an unlock event with the password, pass the synthetic * password provided by the LockSettingService + * @param unlockingSids - KeyMint secure user IDs that should be permitted to unlock + * UNLOCKED_DEVICE_REQUIRED keys. * * @return 0 if successful or a {@code ResponseCode}. */ public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId, - @Nullable byte[] syntheticPassword) { + @Nullable byte[] syntheticPassword, @Nullable long[] unlockingSids) { try { if (locked) { - getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null); + getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null, unlockingSids); } else { - getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword); + getService().onLockScreenEvent( + LockScreenEvent.UNLOCK, userId, syntheticPassword, unlockingSids); } return 0; } catch (RemoteException | NullPointerException e) { diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 117c85bfdf774..ea1c68d1116ed 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1266,7 +1266,7 @@ public class LockSettingsService extends ILockSettings.Stub { private void unlockKeystore(byte[] password, int userHandle) { if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle); - Authorization.onLockScreenEvent(false, userHandle, password); + Authorization.onLockScreenEvent(false, userHandle, password, null); } @VisibleForTesting /** Note: this method is overridden in unit tests */ diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index ff763fccd5ff9..90b095bbbebe8 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -39,6 +39,7 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.database.ContentObserver; import android.graphics.drawable.Drawable; +import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricSourceType; import android.net.Uri; import android.os.Binder; @@ -185,8 +186,6 @@ public class TrustManagerService extends SystemService { private boolean mTrustAgentsCanRun = false; private int mCurrentUser = UserHandle.USER_SYSTEM; - private Authorization mAuthorizationService; - public TrustManagerService(Context context) { super(context); mContext = context; @@ -196,7 +195,6 @@ public class TrustManagerService extends SystemService { mStrongAuthTracker = new StrongAuthTracker(context); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mSettingsObserver = new SettingsObserver(mHandler); - mAuthorizationService = new Authorization(); } @Override @@ -698,13 +696,14 @@ public class TrustManagerService extends SystemService { } if (changed) { dispatchDeviceLocked(userId, locked); - - Authorization.onLockScreenEvent(locked, userId, null); + Authorization.onLockScreenEvent(locked, userId, null, + getBiometricSids(userId)); // Also update the user's profiles who have unified challenge, since they // share the same unlocked state (see {@link #isDeviceLocked(int)}) for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) { if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) { - mAuthorizationService.onLockScreenEvent(locked, profileHandle, null); + Authorization.onLockScreenEvent(locked, profileHandle, null, + getBiometricSids(profileHandle)); } } } @@ -1044,6 +1043,14 @@ public class TrustManagerService extends SystemService { } } + private long[] getBiometricSids(int userId) { + BiometricManager biometricManager = mContext.getSystemService(BiometricManager.class); + if (biometricManager == null) { + return null; + } + return biometricManager.getAuthenticatorIds(userId); + } + // User lifecycle @Override @@ -1255,7 +1262,8 @@ public class TrustManagerService extends SystemService { mDeviceLockedForUser.put(userId, locked); } - Authorization.onLockScreenEvent(locked, userId, null); + Authorization.onLockScreenEvent(locked, userId, null, + getBiometricSids(userId)); if (locked) { try {