Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 336b5db8 authored by Paul Crowley's avatar Paul Crowley
Browse files

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
parent 4459123d
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+15 −7
Original line number Diff line number Diff line
@@ -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 {