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

Commit 3462c832 authored by Bo Zhu's avatar Bo Zhu
Browse files

Refactor PlatformKeyManger to remove mUserId to fix two tests that fail

on clean devices without secure screenlocks

The mUserId is removed to allow a mocked PlatformKeyManager to be passed
into RecoverableKeyStoreManager for tests.

Test: adb shell am instrument -w -e package
com.android.server.locksettings.recoverablekeystore
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner

Change-Id: I9b1fda3c7d869b683cd71cb81ea88da5d995ace9
parent 25e3210e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ public class KeySyncTask implements Runnable {
                userId,
                credentialType,
                credential,
                () -> PlatformKeyManager.getInstance(context, recoverableKeyStoreDb, userId));
                () -> PlatformKeyManager.getInstance(context, recoverableKeyStoreDb));
    }

    /**
@@ -246,7 +246,7 @@ public class KeySyncTask implements Runnable {
            throws InsecureUserException, KeyStoreException, UnrecoverableKeyException,
            NoSuchAlgorithmException, NoSuchPaddingException, BadPlatformKeyException {
        PlatformKeyManager platformKeyManager = mPlatformKeyManagerFactory.newInstance();
        PlatformDecryptionKey decryptKey = platformKeyManager.getDecryptKey();
        PlatformDecryptionKey decryptKey = platformKeyManager.getDecryptKey(mUserId);
        Map<String, WrappedKey> wrappedKeys = mRecoverableKeyStoreDb.getAllKeys(
                mUserId, decryptKey.getGenerationId());
        return WrappedKey.unwrapKeys(decryptKey, wrappedKeys);
+68 −54
Original line number Diff line number Diff line
@@ -71,7 +71,6 @@ public class PlatformKeyManager {
    private final Context mContext;
    private final KeyStoreProxy mKeyStore;
    private final RecoverableKeyStoreDb mDatabase;
    private final int mUserId;

    private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";

@@ -80,34 +79,25 @@ public class PlatformKeyManager {
     * defined by {@code context}.
     *
     * @param context This should be the context of the RecoverableKeyStoreLoader service.
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @throws KeyStoreException if failed to initialize AndroidKeyStore.
     * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
     * @throws InsecureUserException if the user does not have a lock screen set.
     * @throws SecurityException if the caller does not have permission to write to /data/system.
     *
     * @hide
     */
    public static PlatformKeyManager getInstance(Context context, RecoverableKeyStoreDb database,
            int userId)
            throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
        context = context.getApplicationContext();
        PlatformKeyManager keyManager = new PlatformKeyManager(
                userId,
                context,
    public static PlatformKeyManager getInstance(Context context, RecoverableKeyStoreDb database)
            throws KeyStoreException, NoSuchAlgorithmException {
        return new PlatformKeyManager(
                context.getApplicationContext(),
                new KeyStoreProxyImpl(getAndLoadAndroidKeyStore()),
                database);
        keyManager.init();
        return keyManager;
    }

    @VisibleForTesting
    PlatformKeyManager(
            int userId,
            Context context,
            KeyStoreProxy keyStore,
            RecoverableKeyStoreDb database) {
        mUserId = userId;
        mKeyStore = keyStore;
        mContext = context;
        mDatabase = database;
@@ -118,67 +108,91 @@ public class PlatformKeyManager {
     * key has to be replaced. (e.g., because the user has removed and then re-added their lock
     * screen). Returns -1 if no key has been generated yet.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     *
     * @hide
     */
    public int getGenerationId() {
        return mDatabase.getPlatformKeyGenerationId(mUserId);
    public int getGenerationId(int userId) {
        return mDatabase.getPlatformKeyGenerationId(userId);
    }

    /**
     * Returns {@code true} if the platform key is available. A platform key won't be available if
     * the user has not set up a lock screen.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     *
     * @hide
     */
    public boolean isAvailable() {
        return mContext.getSystemService(KeyguardManager.class).isDeviceSecure(mUserId);
    public boolean isAvailable(int userId) {
        return mContext.getSystemService(KeyguardManager.class).isDeviceSecure(userId);
    }

    /**
     * Generates a new key and increments the generation ID. Should be invoked if the platform key
     * is corrupted and needs to be rotated.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
     * @throws KeyStoreException if there is an error in AndroidKeyStore.
     * @throws InsecureUserException if the user does not have a lock screen set.
     *
     * @hide
     */
    public void regenerate() throws NoSuchAlgorithmException, KeyStoreException {
        int nextId = getGenerationId() + 1;
        generateAndLoadKey(nextId);
    public void regenerate(int userId)
            throws NoSuchAlgorithmException, KeyStoreException, InsecureUserException {
        if (!isAvailable(userId)) {
            throw new InsecureUserException(String.format(
                    Locale.US, "%d does not have a lock screen set.", userId));
        }

        int generationId = getGenerationId(userId);
        int nextId;
        if (generationId == -1) {
            nextId = 1;
        } else {
            nextId = generationId + 1;
        }
        generateAndLoadKey(userId, nextId);
    }

    /**
     * Returns the platform key used for encryption.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @throws KeyStoreException if there was an AndroidKeyStore error.
     * @throws UnrecoverableKeyException if the key could not be recovered.
     * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
     * @throws InsecureUserException if the user does not have a lock screen set.
     *
     * @hide
     */
    public PlatformEncryptionKey getEncryptKey()
            throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
        int generationId = getGenerationId();
    public PlatformEncryptionKey getEncryptKey(int userId) throws KeyStoreException,
           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
        init(userId);
        int generationId = getGenerationId(userId);
        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
                getEncryptAlias(generationId), /*password=*/ null);
                getEncryptAlias(userId, generationId), /*password=*/ null);
        return new PlatformEncryptionKey(generationId, key);
    }

    /**
     * Returns the platform key used for decryption. Only works after a recent screen unlock.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @throws KeyStoreException if there was an AndroidKeyStore error.
     * @throws UnrecoverableKeyException if the key could not be recovered.
     * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
     * @throws InsecureUserException if the user does not have a lock screen set.
     *
     * @hide
     */
    public PlatformDecryptionKey getDecryptKey()
            throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
        int generationId = getGenerationId();
    public PlatformDecryptionKey getDecryptKey(int userId) throws KeyStoreException,
           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
        init(userId);
        int generationId = getGenerationId(userId);
        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
                getDecryptAlias(generationId), /*password=*/ null);
                getDecryptAlias(userId, generationId), /*password=*/ null);
        return new PlatformDecryptionKey(generationId, key);
    }

@@ -186,38 +200,36 @@ public class PlatformKeyManager {
     * Initializes the class. If there is no current platform key, and the user has a lock screen
     * set, will create the platform key and set the generation ID.
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @throws KeyStoreException if there was an error in AndroidKeyStore.
     * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
     *
     * @hide
     */
    public void init() throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
        if (!isAvailable()) {
    void init(int userId)
            throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
        if (!isAvailable(userId)) {
            throw new InsecureUserException(String.format(
                    Locale.US, "%d does not have a lock screen set.", mUserId));
                    Locale.US, "%d does not have a lock screen set.", userId));
        }

        int generationId = getGenerationId();
        if (isKeyLoaded(generationId)) {
        int generationId = getGenerationId(userId);
        if (isKeyLoaded(userId, generationId)) {
            Log.i(TAG, String.format(
                    Locale.US, "Platform key generation %d exists already.", generationId));
            return;
        }
        if (generationId == -1) {
            Log.i(TAG, "Generating initial platform ID.");
            generationId = 1;
        } else {
            Log.w(TAG, String.format(Locale.US, "Platform generation ID was %d but no "
                    + "entry was present in AndroidKeyStore. Generating fresh key.", generationId));
        }

        if (generationId == -1) {
            generationId = 1;
        } else {
            // Had to generate a fresh key, bump the generation id
            generationId++;
        }

        generateAndLoadKey(generationId);
        generateAndLoadKey(userId, generationId);
    }

    /**
@@ -227,11 +239,12 @@ public class PlatformKeyManager {
     * <p>These IDs look as follows:
     * {@code com.security.recoverablekeystore/platform/<user id>/<generation id>/encrypt}
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @param generationId The generation ID.
     * @return The alias.
     */
    private String getEncryptAlias(int generationId) {
        return KEY_ALIAS_PREFIX + mUserId + "/" + generationId + "/" + ENCRYPT_KEY_ALIAS_SUFFIX;
    private String getEncryptAlias(int userId, int generationId) {
        return KEY_ALIAS_PREFIX + userId + "/" + generationId + "/" + ENCRYPT_KEY_ALIAS_SUFFIX;
    }

    /**
@@ -241,18 +254,19 @@ public class PlatformKeyManager {
     * <p>These IDs look as follows:
     * {@code com.security.recoverablekeystore/platform/<user id>/<generation id>/decrypt}
     *
     * @param userId The ID of the user to whose lock screen the platform key must be bound.
     * @param generationId The generation ID.
     * @return The alias.
     */
    private String getDecryptAlias(int generationId) {
        return KEY_ALIAS_PREFIX + mUserId + "/" + generationId + "/" + DECRYPT_KEY_ALIAS_SUFFIX;
    private String getDecryptAlias(int userId, int generationId) {
        return KEY_ALIAS_PREFIX + userId + "/" + generationId + "/" + DECRYPT_KEY_ALIAS_SUFFIX;
    }

    /**
     * Sets the current generation ID to {@code generationId}.
     */
    private void setGenerationId(int generationId) {
        mDatabase.setPlatformKeyGenerationId(mUserId, generationId);
    private void setGenerationId(int userId, int generationId) {
        mDatabase.setPlatformKeyGenerationId(userId, generationId);
    }

    /**
@@ -261,9 +275,9 @@ public class PlatformKeyManager {
     *
     * @throws KeyStoreException if there was an error checking AndroidKeyStore.
     */
    private boolean isKeyLoaded(int generationId) throws KeyStoreException {
        return mKeyStore.containsAlias(getEncryptAlias(generationId))
                && mKeyStore.containsAlias(getDecryptAlias(generationId));
    private boolean isKeyLoaded(int userId, int generationId) throws KeyStoreException {
        return mKeyStore.containsAlias(getEncryptAlias(userId, generationId))
                && mKeyStore.containsAlias(getDecryptAlias(userId, generationId));
    }

    /**
@@ -274,10 +288,10 @@ public class PlatformKeyManager {
     *     available since API version 1.
     * @throws KeyStoreException if there was an issue loading the keys into AndroidKeyStore.
     */
    private void generateAndLoadKey(int generationId)
    private void generateAndLoadKey(int userId, int generationId)
            throws NoSuchAlgorithmException, KeyStoreException {
        String encryptAlias = getEncryptAlias(generationId);
        String decryptAlias = getDecryptAlias(generationId);
        String encryptAlias = getEncryptAlias(userId, generationId);
        String decryptAlias = getDecryptAlias(userId, generationId);
        SecretKey secretKey = generateAesKey();

        mKeyStore.setEntry(
@@ -296,10 +310,10 @@ public class PlatformKeyManager {
                            USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setBoundToSpecificSecureUserId(mUserId)
                    .setBoundToSpecificSecureUserId(userId)
                    .build());

        setGenerationId(generationId);
        setGenerationId(userId, generationId);

        try {
            secretKey.destroy();
+22 −9
Original line number Diff line number Diff line
@@ -85,22 +85,34 @@ public class RecoverableKeyStoreManager {
    private final RecoverySnapshotListenersStorage mListenersStorage;
    private final RecoverableKeyGenerator mRecoverableKeyGenerator;
    private final RecoverySnapshotStorage mSnapshotStorage;
    private final PlatformKeyManager mPlatformKeyManager;

    /**
     * Returns a new or existing instance.
     *
     * @hide
     */
    public static synchronized RecoverableKeyStoreManager getInstance(Context mContext) {
    public static synchronized RecoverableKeyStoreManager getInstance(Context context) {
        if (mInstance == null) {
            RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(mContext);
            RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(context);
            PlatformKeyManager platformKeyManager;
            try {
                platformKeyManager = PlatformKeyManager.getInstance(context, db);
            } catch (NoSuchAlgorithmException e) {
                // Impossible: all algorithms must be supported by AOSP
                throw new RuntimeException(e);
            } catch (KeyStoreException e) {
                throw new ServiceSpecificException(ERROR_KEYSTORE_INTERNAL_ERROR, e.getMessage());
            }

            mInstance = new RecoverableKeyStoreManager(
                    mContext.getApplicationContext(),
                    context.getApplicationContext(),
                    db,
                    new RecoverySessionStorage(),
                    Executors.newSingleThreadExecutor(),
                    new RecoverySnapshotStorage(),
                    new RecoverySnapshotListenersStorage());
                    new RecoverySnapshotListenersStorage(),
                    platformKeyManager);
        }
        return mInstance;
    }
@@ -112,13 +124,16 @@ public class RecoverableKeyStoreManager {
            RecoverySessionStorage recoverySessionStorage,
            ExecutorService executorService,
            RecoverySnapshotStorage snapshotStorage,
            RecoverySnapshotListenersStorage listenersStorage) {
            RecoverySnapshotListenersStorage listenersStorage,
            PlatformKeyManager platformKeyManager) {
        mContext = context;
        mDatabase = recoverableKeyStoreDb;
        mRecoverySessionStorage = recoverySessionStorage;
        mExecutorService = executorService;
        mListenersStorage = listenersStorage;
        mSnapshotStorage = snapshotStorage;
        mPlatformKeyManager = platformKeyManager;

        try {
            mRecoverableKeyGenerator = RecoverableKeyGenerator.newInstance(mDatabase);
        } catch (NoSuchAlgorithmException e) {
@@ -380,12 +395,10 @@ public class RecoverableKeyStoreManager {
        int uid = Binder.getCallingUid();
        int userId = UserHandle.getCallingUserId();

        PlatformEncryptionKey encryptionKey;

        PlatformEncryptionKey encryptionKey;
        try {
            PlatformKeyManager platformKeyManager = PlatformKeyManager.getInstance(
                    mContext, mDatabase, userId);
            encryptionKey = platformKeyManager.getEncryptKey();
            encryptionKey = mPlatformKeyManager.getEncryptKey(userId);
        } catch (NoSuchAlgorithmException e) {
            // Impossible: all algorithms must be supported by AOSP
            throw new RuntimeException(e);
+1 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ public class KeySyncTaskTest {

        mWrappingKey = generateAndroidKeyStoreKey();
        mEncryptKey = new PlatformEncryptionKey(TEST_GENERATION_ID, mWrappingKey);
        when(mPlatformKeyManager.getDecryptKey()).thenReturn(
        when(mPlatformKeyManager.getDecryptKey(TEST_USER_ID)).thenReturn(
                new PlatformDecryptionKey(TEST_GENERATION_ID, mWrappingKey));
    }

+33 −37
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public class PlatformKeyManagerTest {
        mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME);
        mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context);
        mPlatformKeyManager = new PlatformKeyManager(
                USER_ID_FIXTURE, mContext, mKeyStoreProxy, mRecoverableKeyStoreDb);
                mContext, mKeyStoreProxy, mRecoverableKeyStoreDb);

        when(mContext.getSystemService(anyString())).thenReturn(mKeyguardManager);
        when(mContext.getSystemServiceName(any())).thenReturn("test");
@@ -93,7 +93,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsEncryptKeyWithCorrectAlias() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).setEntry(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
@@ -103,14 +103,14 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsEncryptKeyWithCorrectPurposes() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(KeyProperties.PURPOSE_ENCRYPT, getEncryptKeyProtection().getPurposes());
    }

    @Test
    public void init_createsEncryptKeyWithCorrectPaddings() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertArrayEquals(
                new String[] { KeyProperties.ENCRYPTION_PADDING_NONE },
@@ -119,7 +119,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsEncryptKeyWithCorrectBlockModes() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertArrayEquals(
                new String[] { KeyProperties.BLOCK_MODE_GCM },
@@ -128,14 +128,14 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsEncryptKeyWithoutAuthenticationRequired() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertFalse(getEncryptKeyProtection().isUserAuthenticationRequired());
    }

    @Test
    public void init_createsDecryptKeyWithCorrectAlias() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).setEntry(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
@@ -145,14 +145,14 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsDecryptKeyWithCorrectPurposes() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(KeyProperties.PURPOSE_DECRYPT, getDecryptKeyProtection().getPurposes());
    }

    @Test
    public void init_createsDecryptKeyWithCorrectPaddings() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertArrayEquals(
                new String[] { KeyProperties.ENCRYPTION_PADDING_NONE },
@@ -161,7 +161,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsDecryptKeyWithCorrectBlockModes() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertArrayEquals(
                new String[] { KeyProperties.BLOCK_MODE_GCM },
@@ -170,14 +170,14 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsDecryptKeyWithAuthenticationRequired() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertTrue(getDecryptKeyProtection().isUserAuthenticationRequired());
    }

    @Test
    public void init_createsDecryptKeyWithAuthenticationValidFor15Seconds() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(
                USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS,
@@ -186,7 +186,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsDecryptKeyBoundToTheUsersAuthentication() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(
                USER_ID_FIXTURE,
@@ -195,7 +195,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_createsBothKeysWithSameMaterial() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        verify(mKeyStoreProxy, times(2)).setEntry(any(), mEntryArgumentCaptor.capture(), any());
        List<KeyStore.Entry> entries = mEntryArgumentCaptor.getAllValues();
@@ -206,7 +206,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_savesGenerationIdToDatabase() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(1,
                mRecoverableKeyStoreDb.getPlatformKeyGenerationId(USER_ID_FIXTURE));
@@ -214,23 +214,23 @@ public class PlatformKeyManagerTest {

    @Test
    public void init_setsGenerationIdTo1() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(1, mPlatformKeyManager.getGenerationId());
        assertEquals(1, mPlatformKeyManager.getGenerationId(USER_ID_FIXTURE));
    }

    @Test
    public void init_incrementsGenerationIdIfKeyIsUnavailable() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(2, mPlatformKeyManager.getGenerationId());
        assertEquals(2, mPlatformKeyManager.getGenerationId(USER_ID_FIXTURE));
    }

    @Test
    public void init_doesNotIncrementGenerationIdIfKeyAvailable() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
@@ -238,21 +238,19 @@ public class PlatformKeyManagerTest {
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);

        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        assertEquals(1, mPlatformKeyManager.getGenerationId());
        assertEquals(1, mPlatformKeyManager.getGenerationId(USER_ID_FIXTURE));
    }

    @Test
    public void getGenerationId_returnsMinusOneIfNotInitialized() throws Exception {
        assertEquals(-1, mPlatformKeyManager.getGenerationId());
        assertEquals(-1, mPlatformKeyManager.getGenerationId(USER_ID_FIXTURE));
    }

    @Test
    public void getDecryptKey_getsDecryptKeyWithCorrectAlias() throws Exception {
        mPlatformKeyManager.init();

        mPlatformKeyManager.getDecryptKey();
        mPlatformKeyManager.getDecryptKey(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
@@ -261,9 +259,7 @@ public class PlatformKeyManagerTest {

    @Test
    public void getEncryptKey_getsDecryptKeyWithCorrectAlias() throws Exception {
        mPlatformKeyManager.init();

        mPlatformKeyManager.getEncryptKey();
        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
@@ -272,18 +268,18 @@ public class PlatformKeyManagerTest {

    @Test
    public void regenerate_incrementsTheGenerationId() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        mPlatformKeyManager.regenerate();
        mPlatformKeyManager.regenerate(USER_ID_FIXTURE);

        assertEquals(2, mPlatformKeyManager.getGenerationId());
        assertEquals(2, mPlatformKeyManager.getGenerationId(USER_ID_FIXTURE));
    }

    @Test
    public void regenerate_generatesANewEncryptKeyWithTheCorrectAlias() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        mPlatformKeyManager.regenerate();
        mPlatformKeyManager.regenerate(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).setEntry(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/encrypt"),
@@ -293,9 +289,9 @@ public class PlatformKeyManagerTest {

    @Test
    public void regenerate_generatesANewDecryptKeyWithTheCorrectAlias() throws Exception {
        mPlatformKeyManager.init();
        mPlatformKeyManager.init(USER_ID_FIXTURE);

        mPlatformKeyManager.regenerate();
        mPlatformKeyManager.regenerate(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).setEntry(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/decrypt"),
Loading