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

Commit 12b644d2 authored by Rubin Xu's avatar Rubin Xu
Browse files

Introduce KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION

This flag is used by system server to mark keys used during the
synthetic password auth flow. keys marked with this flag will not
be super encrypted because super encryption requires knowledge of
the synthetic password, causing a chicken-and-egg problem.

Bug: 35849499
Bug: 34600579
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.MixedProfileOwnerTest#testResetPasswordWithToken

Change-Id: I474822f2e026f24ce6f6de1aa58b5012922f7b13
parent 274442e3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -93,6 +93,16 @@ public class KeyStore {
     */
    public static final int FLAG_ENCRYPTED = 1;

    /**
     * A private flag that's only available to system server to indicate that this key is part of
     * device encryption flow so it receives special treatment from keystore. For example this key
     * will not be super encrypted, and it will be stored separately under an unique UID instead
     * of the caller UID i.e. SYSTEM.
     *
     * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
     */
    public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3;

    // States
    public enum State { UNLOCKED, LOCKED, UNINITIALIZED };

+8 −1
Original line number Diff line number Diff line
@@ -351,6 +351,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
            }
        } else if (param instanceof KeyProtection) {
            spec = (KeyProtection) param;
            if (spec.isCriticalToDeviceEncryption()) {
                flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
            }
        } else {
            throw new KeyStoreException(
                    "Unsupported protection parameter class:" + param.getClass().getName()
@@ -719,6 +722,10 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new KeyStoreException(e);
        }
        int flags = 0;
        if (params.isCriticalToDeviceEncryption()) {
            flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
        }

        Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
        String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias;
@@ -728,7 +735,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
                KeymasterDefs.KM_KEY_FORMAT_RAW,
                keyMaterial,
                mUid,
                0, // flags
                flags,
                new KeyCharacteristics());
        if (errorCode != KeyStore.NO_ERROR) {
            throw new KeyStoreException("Failed to import secret key. Keystore error code: "
+31 −2
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@ public final class KeyProtection implements ProtectionParameter {
    private final boolean mUserAuthenticationValidWhileOnBody;
    private final boolean mInvalidatedByBiometricEnrollment;
    private final long mBoundToSecureUserId;
    private final boolean mCriticalToDeviceEncryption;

    private KeyProtection(
            Date keyValidityStart,
@@ -242,7 +243,8 @@ public final class KeyProtection implements ProtectionParameter {
            int userAuthenticationValidityDurationSeconds,
            boolean userAuthenticationValidWhileOnBody,
            boolean invalidatedByBiometricEnrollment,
            long boundToSecureUserId) {
            long boundToSecureUserId,
            boolean criticalToDeviceEncryption) {
        mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
        mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
        mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -259,6 +261,7 @@ public final class KeyProtection implements ProtectionParameter {
        mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
        mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
        mBoundToSecureUserId = boundToSecureUserId;
        mCriticalToDeviceEncryption = criticalToDeviceEncryption;
    }

    /**
@@ -457,6 +460,16 @@ public final class KeyProtection implements ProtectionParameter {
        return mBoundToSecureUserId;
    }

    /**
     * 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 KeyProtection} instances.
     */
@@ -477,6 +490,7 @@ public final class KeyProtection implements ProtectionParameter {
        private boolean mInvalidatedByBiometricEnrollment = true;

        private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
        private boolean mCriticalToDeviceEncryption = false;
        /**
         * Creates a new instance of the {@code Builder}.
         *
@@ -816,6 +830,20 @@ public final class KeyProtection implements ProtectionParameter {
            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 {@link KeyProtection}.
         *
@@ -837,7 +865,8 @@ public final class KeyProtection implements ProtectionParameter {
                    mUserAuthenticationValidityDurationSeconds,
                    mUserAuthenticationValidWhileOnBody,
                    mInvalidatedByBiometricEnrollment,
                    mBoundToSecureUserId);
                    mBoundToSecureUserId,
                    mCriticalToDeviceEncryption);
        }
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -139,12 +139,14 @@ public class SyntheticPasswordCrypto {
            keyStore.load(null);
            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setCriticalToDeviceEncryption(true);
            if (sid != 0) {
                builder.setUserAuthenticationRequired(true)
                        .setBoundToSpecificSecureUserId(sid)
                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
            }

            keyStore.setEntry(keyAlias,
                    new KeyStore.SecretKeyEntry(secretKey),
                    builder.build());