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

Commit a7f1d718 authored by Janis Danisevskis's avatar Janis Danisevskis
Browse files

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.
Merged-In: I6e92a08a6b3145891585a134c195c4e29be709b5
Change-Id: I6e92a08a6b3145891585a134c195c4e29be709b5
parent 2a66fc61
Loading
Loading
Loading
Loading
+16 −5
Original line number Original line Diff line number Diff line
@@ -154,6 +154,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
@@ -261,7 +262,13 @@ public class LockSettingsService extends ILockSettings.Stub {


        @Override
        @Override
        public void onStart() {
        public void onStart() {
            Optional<Boolean> keystore2_enabled =
                    android.sysprop.Keystore2Properties.keystore2_enabled();
            if (keystore2_enabled.isPresent() && keystore2_enabled.get()) {
                android.security.keystore2.AndroidKeyStoreProvider.install();
            } else {
                AndroidKeyStoreProvider.install();
                AndroidKeyStoreProvider.install();
            }
            mLockSettingsService = new LockSettingsService(getContext());
            mLockSettingsService = new LockSettingsService(getContext());
            publishBinderService("lock_settings", mLockSettingsService);
            publishBinderService("lock_settings", mLockSettingsService);
        }
        }
@@ -542,7 +549,8 @@ public class LockSettingsService extends ILockSettings.Stub {


        public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() {
        public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() {
            try {
            try {
                java.security.KeyStore ks = java.security.KeyStore.getInstance("AndroidKeyStore");
                java.security.KeyStore ks = java.security.KeyStore.getInstance(
                        SyntheticPasswordCrypto.androidKeystoreProviderName());
                ks.load(null);
                ks.load(null);
                return new ManagedProfilePasswordCache(ks, getUserManager());
                return new ManagedProfilePasswordCache(ks, getUserManager());
            } catch (Exception e) {
            } catch (Exception e) {
@@ -1284,7 +1292,8 @@ public class LockSettingsService extends ILockSettings.Stub {
        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
                storedData.length);
                storedData.length);
        byte[] decryptionResult;
        byte[] decryptionResult;
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
        java.security.KeyStore keyStore = java.security.KeyStore.getInstance(
                SyntheticPasswordCrypto.androidKeystoreProviderName());
        keyStore.load(null);
        keyStore.load(null);
        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
@@ -1743,7 +1752,8 @@ public class LockSettingsService extends ILockSettings.Stub {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
            keyGenerator.init(new SecureRandom());
            keyGenerator.init(new SecureRandom());
            SecretKey secretKey = keyGenerator.generateKey();
            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);
            keyStore.load(null);
            try {
            try {
                keyStore.setEntry(
                keyStore.setEntry(
@@ -2299,7 +2309,8 @@ public class LockSettingsService extends ILockSettings.Stub {
    private void removeKeystoreProfileKey(int targetUserId) {
    private void removeKeystoreProfileKey(int targetUserId) {
        Slog.i(TAG, "Remove keystore profile key for user: " + targetUserId);
        Slog.i(TAG, "Remove keystore profile key for user: " + targetUserId);
        try {
        try {
            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
            java.security.KeyStore keyStore = java.security.KeyStore.getInstance(
                    SyntheticPasswordCrypto.androidKeystoreProviderName());
            keyStore.load(null);
            keyStore.load(null);
            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
+20 −4
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.locksettings;


import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore.KeyProtection;
import android.security.keystore2.AndroidKeyStoreProvider;
import android.util.Slog;
import android.util.Slog;


import java.io.ByteArrayOutputStream;
import java.io.ByteArrayOutputStream;
@@ -125,7 +126,7 @@ public class SyntheticPasswordCrypto {


    public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
    public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
        try {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
            keyStore.load(null);
            keyStore.load(null);


            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, 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) {
    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
        try {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
            keyStore.load(null);
            keyStore.load(null);


            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
@@ -166,7 +182,7 @@ public class SyntheticPasswordCrypto {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
            keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
            keyGenerator.init(AES_KEY_LENGTH * 8, new SecureRandom());
            SecretKey secretKey = keyGenerator.generateKey();
            SecretKey secretKey = keyGenerator.generateKey();
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
            keyStore.load(null);
            keyStore.load(null);
            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
@@ -196,7 +212,7 @@ public class SyntheticPasswordCrypto {
    public static void destroyBlobKey(String keyAlias) {
    public static void destroyBlobKey(String keyAlias) {
        KeyStore keyStore;
        KeyStore keyStore;
        try {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore = KeyStore.getInstance(androidKeystoreProviderName());
            keyStore.load(null);
            keyStore.load(null);
            keyStore.deleteEntry(keyAlias);
            keyStore.deleteEntry(keyAlias);
            Slog.i(TAG, "SP key deleted: " + keyAlias);
            Slog.i(TAG, "SP key deleted: " + keyAlias);