From b9e7ae352b6a724627d5f8a41ac09e21e15af6b6 Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Tue, 20 Oct 2020 09:25:44 -0700 Subject: [PATCH] Keystore 2.0 SPI: Make LockSettingsService tolerate the Keystore 2.0 SPI This patch adds support for using the Legacy Keystore provider when the Keystore 2.0 provider is installed. This is the first step towards the transition to Keystore 2.0. Installation of the new provider can be triggered by setting the platform property ro.android.security.keystore2.enable=true. Bug: 171305115 Test: The system still boots with and without the new SPI being installed. And users can still unlock the phone. Change-Id: I6e92a08a6b3145891585a134c195c4e29be709b5 --- .../locksettings/LockSettingsService.java | 21 ++++++++++++---- .../locksettings/SyntheticPasswordCrypto.java | 24 +++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index c42c84f75051d..ad96e7633283b 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -156,6 +156,7 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; import java.util.Random; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -261,7 +262,13 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void onStart() { - AndroidKeyStoreProvider.install(); + Optional keystore2_enabled = + android.sysprop.Keystore2Properties.keystore2_enabled(); + if (keystore2_enabled.isPresent() && keystore2_enabled.get()) { + android.security.keystore2.AndroidKeyStoreProvider.install(); + } else { + AndroidKeyStoreProvider.install(); + } mLockSettingsService = new LockSettingsService(getContext()); publishBinderService("lock_settings", mLockSettingsService); } @@ -533,7 +540,8 @@ public class LockSettingsService extends ILockSettings.Stub { public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() { try { - java.security.KeyStore ks = java.security.KeyStore.getInstance("AndroidKeyStore"); + java.security.KeyStore ks = java.security.KeyStore.getInstance( + SyntheticPasswordCrypto.androidKeystoreProviderName()); ks.load(null); return new ManagedProfilePasswordCache(ks, getUserManager()); } catch (Exception e) { @@ -1281,7 +1289,8 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE, storedData.length); byte[] decryptionResult; - java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + java.security.KeyStore keyStore = java.security.KeyStore.getInstance( + SyntheticPasswordCrypto.androidKeystoreProviderName()); keyStore.load(null); SecretKey decryptionKey = (SecretKey) keyStore.getKey( LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null); @@ -1717,7 +1726,8 @@ public class LockSettingsService extends ILockSettings.Stub { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); - java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + java.security.KeyStore keyStore = java.security.KeyStore.getInstance( + SyntheticPasswordCrypto.androidKeystoreProviderName()); keyStore.load(null); try { keyStore.setEntry( @@ -2291,7 +2301,8 @@ public class LockSettingsService extends ILockSettings.Stub { private void removeKeystoreProfileKey(int targetUserId) { Slog.i(TAG, "Remove keystore profile key for user: " + targetUserId); try { - java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + java.security.KeyStore keyStore = java.security.KeyStore.getInstance( + SyntheticPasswordCrypto.androidKeystoreProviderName()); keyStore.load(null); keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId); keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId); diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java index 9246311fcdc70..6d420a95e26c3 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java @@ -18,6 +18,7 @@ package com.android.server.locksettings; import android.security.keystore.KeyProperties; import android.security.keystore.KeyProtection; +import android.security.keystore2.AndroidKeyStoreProvider; import android.util.Slog; import java.io.ByteArrayOutputStream; @@ -125,7 +126,7 @@ public class SyntheticPasswordCrypto { public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) { try { - KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); + KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName()); keyStore.load(null); SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null); @@ -140,9 +141,24 @@ public class SyntheticPasswordCrypto { } } + /** + * TODO This function redirects keystore access to the legacy keystore during a transitional + * phase during which not all calling code has been adjusted to use Keystore 2.0. + * This can be reverted to a constant of "AndroidKeyStore" when b/171305684 is complete. + * The specific bug for this component is b/171305115. + */ + static String androidKeystoreProviderName() { + if (AndroidKeyStoreProvider.isInstalled()) { + return "AndroidKeyStoreLegacy"; + } else { + return "AndroidKeystore"; + } + + } + public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) { try { - KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); + KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName()); keyStore.load(null); SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null); @@ -166,7 +182,7 @@ public class SyntheticPasswordCrypto { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); - KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); + KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName()); keyStore.load(null); KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) @@ -196,7 +212,7 @@ public class SyntheticPasswordCrypto { public static void destroyBlobKey(String keyAlias) { KeyStore keyStore; try { - keyStore = KeyStore.getInstance("AndroidKeyStore"); + keyStore = KeyStore.getInstance(androidKeystoreProviderName()); keyStore.load(null); keyStore.deleteEntry(keyAlias); Slog.i(TAG, "SP key deleted: " + keyAlias);