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

Commit 46777a7f authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge changes I55c7f841,Ic77dcdb3,I391533ae into main

* changes:
  Cleanly handle unknown response codes in setLockCredentialInternal()
  Fix response code checks in LockSettingsServiceTests
  Zeroize weaverSecret in unlockLskfBasedProtector()
parents 1cf45a96 2ae403a0
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -1925,18 +1925,22 @@ public class LockSettingsService extends ILockSettings.Stub {
    /**
     * Set a new LSKF for the given user/profile. Only succeeds if the synthetic password for the
     * user is protected by the given {@param savedCredential}.
     * <p>
     * When setting a new credential where there was none, updates the strong auth state for
     *
     * <p>When setting a new credential where there was none, updates the strong auth state for
     * {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>.
     *
     * @param savedCredential if the user is a profile with unified challenge and savedCredential is
     *     empty, LSS will try to re-derive the profile password internally.
     *     TODO (b/80170828): Fix this so profile password is always passed in.
     *     empty, LSS will try to re-derive the profile password internally. TODO (b/80170828): Fix
     *     this so profile password is always passed in.
     * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new
     *     credentials are being tied to its parent's credentials.
     * @return {@code false} if verification of savedCredential failed
     */
    private boolean setLockCredentialInternal(LockscreenCredential credential,
            LockscreenCredential savedCredential, int userId, boolean isLockTiedToParent) {
    private boolean setLockCredentialInternal(
            LockscreenCredential credential,
            LockscreenCredential savedCredential,
            int userId,
            boolean isLockTiedToParent) {
        Objects.requireNonNull(credential);
        Objects.requireNonNull(savedCredential);
        synchronized (mSpManager) {
@@ -1961,18 +1965,14 @@ public class LockSettingsService extends ILockSettings.Stub {
            SyntheticPassword sp = authResult.syntheticPassword;

            if (sp == null) {
                if (response == null
                        || response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
                if (response != null
                        && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                    Slog.w(TAG, "Failed to enroll: rate limit exceeded.");
                } else {
                    Slog.w(TAG, "Failed to enroll: incorrect credential.");
                    return false;
                }
                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                    Slog.w(TAG, "Failed to enroll: rate limit exceeded.");
                return false;
            }
                // Should not be reachable, but just in case.
                throw new IllegalStateException("password change failed");
            }

            onSyntheticPasswordUnlocked(userId, sp);
            setLockCredentialWithSpLocked(credential, sp, userId);
+4 −1
Original line number Diff line number Diff line
@@ -1428,6 +1428,7 @@ class SyntheticPasswordManager {

        byte[] stretchedLskf = null;
        byte[] weaverKey = null;
        byte[] weaverSecret = null;
        byte[] gkPassword = null;
        byte[] protectorSecret = null;
        try {
@@ -1445,11 +1446,12 @@ class SyntheticPasswordManager {
                }
                weaverKey = stretchedLskfToWeaverKey(stretchedLskf);
                WeaverReadResponse weaverResponse = weaverVerify(weaver, weaverSlot, weaverKey);
                weaverSecret = weaverResponse.value;
                if (weaverResponse.status != WeaverReadStatus.OK) {
                    result.response = verifyCredentialResponseFromWeaverResponse(weaverResponse);
                    return result;
                }
                protectorSecret = transformUnderWeaverSecret(stretchedLskf, weaverResponse.value);
                protectorSecret = transformUnderWeaverSecret(stretchedLskf, weaverSecret);
            } else {
                // Weaver is unavailable, so the protector uses Gatekeeper to verify the LSKF,
                // unless the LSKF is empty in which case Gatekeeper might not have been used at
@@ -1542,6 +1544,7 @@ class SyntheticPasswordManager {
        } finally {
            ArrayUtils.zeroize(stretchedLskf);
            ArrayUtils.zeroize(weaverKey);
            ArrayUtils.zeroize(weaverSecret);
            ArrayUtils.zeroize(gkPassword);
            ArrayUtils.zeroize(protectorSecret);
        }
+4 −6
Original line number Diff line number Diff line
@@ -45,12 +45,9 @@ import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.gatekeeper.GateKeeperResponse;
import android.text.TextUtils;

import androidx.test.filters.SmallTest;
@@ -744,7 +741,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
        VerifyCredentialResponse response = mService.verifyCredential(credential, userId,
                0 /* flags */);

        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
        assertEquals(VerifyCredentialResponse.RESPONSE_OK, response.getResponseCode());
        if (credential.isPassword()) {
            assertEquals(CREDENTIAL_TYPE_PASSWORD, mService.getCredentialType(userId));
        } else if (credential.isPin()) {
@@ -762,8 +759,9 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
        } else {
            badCredential = LockscreenCredential.createPin("0");
        }
        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(
                badCredential, userId, 0 /* flags */).getResponseCode());
        assertEquals(
                VerifyCredentialResponse.RESPONSE_ERROR,
                mService.verifyCredential(badCredential, userId, 0 /* flags */).getResponseCode());
    }

    private void setAndVerifyCredential(int userId, LockscreenCredential newCredential)