summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java135
2 files changed, 138 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index 3a78f950675e..e5ff5b83704f 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -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.
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index f9ffccdd5d38..0f0e3f386fec 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -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);
@@ -264,6 +267,56 @@ public class PlatformKeyManagerTest {
}
@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(
eq("com.android.server.locksettings.recoverablekeystore/platform/42/1/encrypt"),
@@ -274,7 +327,13 @@ public class PlatformKeyManagerTest {
+ "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);