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

Commit 7831a4db authored by Bo Zhu's avatar Bo Zhu Committed by Android (Google) Code Review
Browse files

Merge "Try to check the platform decryption key is still accessible before...

Merge "Try to check the platform decryption key is still accessible before using the platform encryption key"
parents cffb3604 1170a78f
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -194,6 +194,9 @@ public class PlatformKeyManager {
           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
        init(userId);
        try {
            // Try to see if the decryption key is still accessible before using the encryption key.
            // The auth-bound decryption will be unrecoverable if the screen lock is disabled.
            getDecryptKeyInternal(userId);
            return getEncryptKeyInternal(userId);
        } catch (UnrecoverableKeyException e) {
            Log.i(TAG, String.format(Locale.US,
@@ -219,7 +222,7 @@ public class PlatformKeyManager {
           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
        int generationId = getGenerationId(userId);
        String alias = getEncryptAlias(userId, generationId);
        if (!mKeyStore.containsAlias(alias)) {
        if (!isKeyLoaded(userId, generationId)) {
            throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
        }
        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
@@ -268,7 +271,7 @@ public class PlatformKeyManager {
           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
        int generationId = getGenerationId(userId);
        String alias = getDecryptAlias(userId, generationId);
        if (!mKeyStore.containsAlias(alias)) {
        if (!isKeyLoaded(userId, generationId)) {
            throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
        }
        AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
@@ -300,12 +303,12 @@ public class PlatformKeyManager {
            return;
        }
        if (generationId == -1) {
            Log.i(TAG, "Generating initial platform ID.");
            Log.i(TAG, "Generating initial platform key generation 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));
            // Had to generate a fresh key, bump the generation id
            // Have to generate a fresh key, so bump the generation id
            generationId++;
        }

@@ -374,7 +377,7 @@ public class PlatformKeyManager {
        String decryptAlias = getDecryptAlias(userId, generationId);
        SecretKey secretKey = generateAesKey();

        // Store Since decryption key first since it is more likely to fail.
        // Store decryption key first since it is more likely to fail.
        mKeyStore.setEntry(
                decryptAlias,
                new KeyStore.SecretKeyEntry(secretKey),
@@ -386,7 +389,6 @@ public class PlatformKeyManager {
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setBoundToSpecificSecureUserId(userId)
                    .build());

        mKeyStore.setEntry(
                encryptAlias,
                new KeyStore.SecretKeyEntry(secretKey),
@@ -397,11 +399,7 @@ public class PlatformKeyManager {

        setGenerationId(userId, generationId);

        try {
            secretKey.destroy();
        } catch (DestroyFailedException e) {
            Log.w(TAG, "Failed to destroy in-memory platform key.", e);
        }
        // TODO: Use a reliable way to destroy the temporary secretKey in memory.
    }

    /**
+129 −6
Original line number Diff line number Diff line
@@ -255,6 +255,9 @@ public class PlatformKeyManagerTest {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);

        mPlatformKeyManager.getDecryptKey(USER_ID_FIXTURE);

@@ -263,6 +266,56 @@ public class PlatformKeyManagerTest {
                any());
    }

    @Test
    public void getDecryptKey_generatesNewKeyIfOldDecryptKeyWasRemoved() throws Exception {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(false); // was removed
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true); // new version is available
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getDecryptKey(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).containsAlias(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"));
        // Attempt to get regenerated key.
        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/decrypt"),
                any());
    }

    @Test
    public void getDecryptKey_generatesNewKeyIfOldEncryptKeyWasRemoved() throws Exception {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(false); // was removed
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getDecryptKey(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).containsAlias(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"));
        // Attempt to get regenerated key.
        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/decrypt"),
                any());
    }

    @Test
    public void getEncryptKey_generatesNewKeyIfOldOneIsInvalid() throws Exception {
        doThrow(new UnrecoverableKeyException()).when(mKeyStoreProxy).getKey(
@@ -272,9 +325,15 @@ public class PlatformKeyManagerTest {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);

@@ -295,11 +354,16 @@ public class PlatformKeyManagerTest {

        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(false); // was removed.

                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true); // new version is available
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getDecryptKey(USER_ID_FIXTURE);

@@ -312,14 +376,70 @@ public class PlatformKeyManagerTest {
    }

    @Test
    public void getEncryptKey_generatesNewKeyIfOldWasRemoved() throws Exception {
    public void getEncryptKey_generatesNewKeyIfDecryptKeyIsUnrecoverable() throws Exception {
        doThrow(new UnrecoverableKeyException()).when(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/decrypt"),
                any());
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(false); // was removed
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true); // new version is available
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(false); // was removed.
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);

        // Attempt to get regenerated key.
        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/encrypt"),
                any());
    }

    @Test
    public void getEncryptKey_generatesNewKeyIfOldDecryptKeyWasRemoved() throws Exception {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(false); // was removed
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true); // new version is available
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);

        verify(mKeyStoreProxy).containsAlias(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"));
        // Attempt to get regenerated key.
        verify(mKeyStoreProxy).getKey(
                eq("com.android.server.locksettings.recoverablekeystore/platform/42/2/encrypt"),
                any());
    }

    @Test
    public void getEncryptKey_generatesNewKeyIfOldEncryptKeyWasRemoved() throws Exception {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(false); // was removed
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/2/decrypt")).thenReturn(true);

        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);

@@ -332,10 +452,13 @@ public class PlatformKeyManagerTest {
    }

    @Test
    public void getEncryptKey_getsEndryptKeyWithCorrectAlias() throws Exception {
    public void getEncryptKey_getsEncryptKeyWithCorrectAlias() throws Exception {
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/encrypt")).thenReturn(true);
        when(mKeyStoreProxy
                .containsAlias("com.android.server.locksettings.recoverablekeystore/"
                        + "platform/42/1/decrypt")).thenReturn(true);

        mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE);