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

Commit b9e7ae35 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.
Change-Id: I6e92a08a6b3145891585a134c195c4e29be709b5
parent f15a5fc2
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -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() {
            Optional<Boolean> 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);
+20 −4
Original line number Diff line number Diff line
@@ -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);