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

Commit b3a13e1e authored by Rubin Xu's avatar Rubin Xu
Browse files

Add KeyGenParameterSpec.setCriticalToDeviceEncryption

Mirror KeyProtection.setCriticalToDeviceEncryption so
the flag can also be set on keys generated by keystore.

Bug: 72178550
Test: atest android.security.keystore.KeyGenParameterSpecTest
Test: atest android.security.ParcelableKeyGenParameterSpecTest
Change-Id: I7f102c82e60f211028c694d499ffd2838b89bb2b
parent d69517eb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -308,6 +308,9 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
        if (spec.isStrongBoxBacked()) {
            flags |= KeyStore.FLAG_STRONGBOX;
        }
        if (spec.isCriticalToDeviceEncryption()) {
            flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
        }
        String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + spec.getKeystoreAlias();
        KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
        boolean success = false;
+3 −2
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@ package android.security.keystore;

import android.annotation.Nullable;
import android.security.Credentials;
import android.security.GateKeeper;
import android.security.KeyPairGeneratorSpec;
import android.security.KeyStore;
import android.security.KeyStoreException;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterCertificateChain;
@@ -458,6 +456,9 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
        if (mSpec.isStrongBoxBacked()) {
            flags |= KeyStore.FLAG_STRONGBOX;
        }
        if (mSpec.isCriticalToDeviceEncryption()) {
            flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
        }

        byte[] additionalEntropy =
                KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
+32 −2
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
    private final boolean mIsStrongBoxBacked;
    private final boolean mUserConfirmationRequired;
    private final boolean mUnlockedDeviceRequired;
    private final boolean mCriticalToDeviceEncryption;
    /*
     * ***NOTE***: All new fields MUST also be added to the following:
     * ParcelableKeyGenParameterSpec class.
@@ -307,7 +308,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
            boolean invalidatedByBiometricEnrollment,
            boolean isStrongBoxBacked,
            boolean userConfirmationRequired,
            boolean unlockedDeviceRequired) {
            boolean unlockedDeviceRequired,
            boolean criticalToDeviceEncryption) {
        if (TextUtils.isEmpty(keyStoreAlias)) {
            throw new IllegalArgumentException("keyStoreAlias must not be empty");
        }
@@ -357,6 +359,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
        mIsStrongBoxBacked = isStrongBoxBacked;
        mUserConfirmationRequired = userConfirmationRequired;
        mUnlockedDeviceRequired = unlockedDeviceRequired;
        mCriticalToDeviceEncryption = criticalToDeviceEncryption;
    }

    /**
@@ -709,6 +712,16 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
        return GateKeeper.INVALID_SECURE_USER_ID;
    }

    /**
     * Return whether this key is critical to the device encryption flow.
     *
     * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION
     * @hide
     */
    public boolean isCriticalToDeviceEncryption() {
        return mCriticalToDeviceEncryption;
    }

    /**
     * Builder of {@link KeyGenParameterSpec} instances.
     */
@@ -741,6 +754,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
        private boolean mIsStrongBoxBacked = false;
        private boolean mUserConfirmationRequired;
        private boolean mUnlockedDeviceRequired = false;
        private boolean mCriticalToDeviceEncryption = false;

        /**
         * Creates a new instance of the {@code Builder}.
@@ -804,6 +818,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
            mIsStrongBoxBacked = sourceSpec.isStrongBoxBacked();
            mUserConfirmationRequired = sourceSpec.isUserConfirmationRequired();
            mUnlockedDeviceRequired = sourceSpec.isUnlockedDeviceRequired();
            mCriticalToDeviceEncryption = sourceSpec.isCriticalToDeviceEncryption();
        }

        /**
@@ -1338,6 +1353,20 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
            return this;
        }

        /**
         * Set whether this key is critical to the device encryption flow
         *
         * This is a special flag only available to system servers to indicate the current key
         * is part of the device encryption flow.
         *
         * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION
         * @hide
         */
        public Builder setCriticalToDeviceEncryption(boolean critical) {
            mCriticalToDeviceEncryption = critical;
            return this;
        }

        /**
         * Builds an instance of {@code KeyGenParameterSpec}.
         */
@@ -1370,7 +1399,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
                    mInvalidatedByBiometricEnrollment,
                    mIsStrongBoxBacked,
                    mUserConfirmationRequired,
                    mUnlockedDeviceRequired);
                    mUnlockedDeviceRequired,
                    mCriticalToDeviceEncryption);
        }
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package android.security.keystore;

import android.os.Parcelable;
import android.os.Parcel;
import android.os.Parcelable;

import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
@@ -105,6 +105,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
        out.writeBoolean(mSpec.isStrongBoxBacked());
        out.writeBoolean(mSpec.isUserConfirmationRequired());
        out.writeBoolean(mSpec.isUnlockedDeviceRequired());
        out.writeBoolean(mSpec.isCriticalToDeviceEncryption());
    }

    private static Date readDateOrNull(Parcel in) {
@@ -160,6 +161,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
        final boolean isStrongBoxBacked = in.readBoolean();
        final boolean userConfirmationRequired = in.readBoolean();
        final boolean unlockedDeviceRequired = in.readBoolean();
        final boolean criticalToDeviceEncryption = in.readBoolean();
        // The KeyGenParameterSpec is intentionally not constructed using a Builder here:
        // The intention is for this class to break if new parameters are added to the
        // KeyGenParameterSpec constructor (whereas using a builder would silently drop them).
@@ -190,7 +192,8 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
                invalidatedByBiometricEnrollment,
                isStrongBoxBacked,
                userConfirmationRequired,
                unlockedDeviceRequired);
                unlockedDeviceRequired,
                criticalToDeviceEncryption);
    }

    public static final @android.annotation.NonNull Creator<ParcelableKeyGenParameterSpec> CREATOR = new Creator<ParcelableKeyGenParameterSpec>() {
+2 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public final class ParcelableKeyGenParameterSpecTest {
                .setIsStrongBoxBacked(true)
                .setUserConfirmationRequired(true)
                .setUnlockedDeviceRequired(true)
                .setCriticalToDeviceEncryption(true)
                .build();
    }

@@ -115,6 +116,7 @@ public final class ParcelableKeyGenParameterSpecTest {
        assertThat(spec.isStrongBoxBacked(), is(true));
        assertThat(spec.isUserConfirmationRequired(), is(true));
        assertThat(spec.isUnlockedDeviceRequired(), is(true));
        assertThat(spec.isCriticalToDeviceEncryption(), is(true));
    }

    private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) {