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

Commit da464f35 authored by Andrew Scull's avatar Andrew Scull Committed by Android (Google) Code Review
Browse files

Merge "Make us of the authsecret HAL."

parents 579642a2 e6527c12
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ java_library_static {
    static_libs: [
        "time_zone_distro",
        "time_zone_distro_installer",
        "android.hardware.authsecret-V1.0-java",
        "android.hardware.broadcastradio-V2.0-java",
        "android.hardware.health-V1.0-java",
        "android.hardware.health-V2.0-java",
+26 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.sqlite.SQLiteDatabase;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -126,8 +127,10 @@ import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@@ -183,6 +186,7 @@ public class LockSettingsService extends ILockSettings.Stub {

    private boolean mFirstCallToVold;
    protected IGateKeeperService mGateKeeperService;
    protected IAuthSecret mAuthSecretService;

    /**
     * The UIDs that are used for system credential storage in keystore.
@@ -613,6 +617,14 @@ public class LockSettingsService extends ILockSettings.Stub {
        } catch (RemoteException e) {
            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
        }
        // Find the AuthSecret HAL
        try {
            mAuthSecretService = IAuthSecret.getService();
        } catch (NoSuchElementException e) {
            Slog.i(TAG, "Device doesn't implement AuthSecret HAL");
        } catch (RemoteException e) {
            Slog.w(TAG, "Failed to get AuthSecret HAL", e);
        }
        mDeviceProvisionedObserver.onSystemReady();
        // TODO: maybe skip this for split system user mode.
        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
@@ -2127,6 +2139,20 @@ public class LockSettingsService extends ILockSettings.Stub {
    private SparseArray<AuthenticationToken> mSpCache = new SparseArray();

    private void onAuthTokenKnownForUser(@UserIdInt int userId, AuthenticationToken auth) {
        // Pass the primary user's auth secret to the HAL
        if (mAuthSecretService != null && mUserManager.getUserInfo(userId).isPrimary()) {
            try {
                final byte[] rawSecret = auth.deriveVendorAuthSecret();
                final ArrayList<Byte> secret = new ArrayList<>(rawSecret.length);
                for (int i = 0; i < rawSecret.length; ++i) {
                    secret.add(rawSecret[i]);
                }
                mAuthSecretService.primaryUserCredential(secret);
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed to pass primary user secret to AuthSecret HAL", e);
            }
        }

        // Update the SP cache, removing the entry when allowed
        synchronized (mSpManager) {
            if (shouldCacheSpForUser(userId)) {
+6 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ public class SyntheticPasswordManager {
    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
    private static final byte[] PERSONALIZATION_AUTHSECRET_KEY = "authsecret-hal".getBytes();
    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
    private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
@@ -159,6 +160,11 @@ public class SyntheticPasswordManager {
                    syntheticPassword.getBytes());
        }

        public byte[] deriveVendorAuthSecret() {
            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_AUTHSECRET_KEY,
                    syntheticPassword.getBytes());
        }

        private void initialize(byte[] P0, byte[] P1) {
            this.P1 = P1;
            this.syntheticPassword = String.valueOf(HexEncoding.encode(
+8 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.app.admin.DevicePolicyManagerInternal;
import android.app.trust.TrustManager;
import android.content.ComponentName;
import android.content.pm.UserInfo;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.os.FileUtils;
import android.os.IProgressListener;
import android.os.RemoteException;
@@ -80,6 +81,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase {
    DevicePolicyManagerInternal mDevicePolicyManagerInternal;
    KeyStore mKeyStore;
    MockSyntheticPasswordManager mSpManager;
    IAuthSecret mAuthSecretService;

    @Override
    protected void setUp() throws Exception {
@@ -115,17 +117,21 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase {
        };
        mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
                mUserManager);
        mAuthSecretService = mock(IAuthSecret.class);
        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
                mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
                mSpManager);
                mSpManager, mAuthSecretService);
        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
        installChildProfile(MANAGED_PROFILE_USER_ID);
        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
        when(mUserManager.getUsers(anyBoolean())).thenReturn(mPrimaryUserProfiles);
        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);

        final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
        allUsers.add(SECONDARY_USER_INFO);
        when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);

        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
                new Answer<Boolean>() {
            @Override
+25 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSW
import static com.android.server.testutils.TestUtils.assertExpectException;

import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

@@ -31,6 +32,10 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;

import java.util.ArrayList;

import org.mockito.ArgumentCaptor;

/**
 * Run the synthetic password tests with caching enabled.
 *
@@ -88,6 +93,26 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
                    .getResponseCode());
    }

    public void testUntrustedCredentialChangeMaintainsAuthSecret() throws RemoteException {
        final String PASSWORD = "testUntrustedCredentialChangeMaintainsAuthSecret-password";
        final String NEWPASSWORD = "testUntrustedCredentialChangeMaintainsAuthSecret-newpassword";

        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
        // Untrusted change password
        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);

        // Verify the password
        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                    .getResponseCode());

        // Ensure the same secret was passed each time
        ArgumentCaptor<ArrayList<Byte>> secret = ArgumentCaptor.forClass(ArrayList.class);
        verify(mAuthSecretService, atLeastOnce()).primaryUserCredential(secret.capture());
        assertEquals(1, secret.getAllValues().stream().distinct().count());
    }

    public void testUntrustedCredentialChangeBlockedIfSpNotCached() throws RemoteException {
        final String PASSWORD = "testUntrustedCredentialChangeBlockedIfSpNotCached-password";
        final String NEWPASSWORD = "testUntrustedCredentialChangeBlockedIfSpNotCached-newpassword";
Loading