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

Commit 7c8628cd authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge changes I05f3b7e5,Ifcfd0b8f

* changes:
  Request rollback resistance for SP protector keys
  AndroidKeyStore: support platform use of rollback-resistant keys
parents ca2f10a8 0f7dea90
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
    private final boolean mUnlockedDeviceRequired;
    private final boolean mIsStrongBoxBacked;
    private final int mMaxUsageCount;
    private final boolean mRollbackResistant;

    private KeyProtection(
            Date keyValidityStart,
@@ -259,7 +260,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
            boolean userConfirmationRequired,
            boolean unlockedDeviceRequired,
            boolean isStrongBoxBacked,
            int maxUsageCount) {
            int maxUsageCount,
            boolean rollbackResistant) {
        mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
        mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
        mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -283,6 +285,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
        mUnlockedDeviceRequired = unlockedDeviceRequired;
        mIsStrongBoxBacked = isStrongBoxBacked;
        mMaxUsageCount = maxUsageCount;
        mRollbackResistant = rollbackResistant;
    }

    /**
@@ -562,6 +565,17 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
        return mMaxUsageCount;
    }

    /**
     * Returns {@code true} if the key is rollback-resistant, meaning that when deleted it is
     * guaranteed to be permanently deleted and unusable.
     *
     * @see Builder#setRollbackResistant(boolean)
     * @hide
     */
    public boolean isRollbackResistant() {
        return mRollbackResistant;
    }

    /**
     * Builder of {@link KeyProtection} instances.
     */
@@ -591,6 +605,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
        private boolean mIsStrongBoxBacked = false;
        private int mMaxUsageCount = KeyProperties.UNRESTRICTED_USAGE_COUNT;
        private String mAttestKeyAlias = null;
        private boolean mRollbackResistant = false;

        /**
         * Creates a new instance of the {@code Builder}.
@@ -1096,6 +1111,21 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
            throw new IllegalArgumentException("maxUsageCount is not valid");
        }

        /**
         * Sets whether the key should be rollback-resistant, meaning that when deleted it is
         * guaranteed to be permanently deleted and unusable.  Not all implementations support
         * rollback-resistant keys.  This method is hidden because implementations only support a
         * limited number of rollback-resistant keys; currently the available space is reserved for
         * critical system keys.
         *
         * @hide
         */
        @NonNull
        public Builder setRollbackResistant(boolean rollbackResistant) {
            mRollbackResistant = rollbackResistant;
            return this;
        }

        /**
         * Builds an instance of {@link KeyProtection}.
         *
@@ -1124,7 +1154,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
                    mUserConfirmationRequired,
                    mUnlockedDeviceRequired,
                    mIsStrongBoxBacked,
                    mMaxUsageCount);
                    mMaxUsageCount,
                    mRollbackResistant);
        }
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -783,6 +783,12 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
                        params.getMaxUsageCount()
                ));
            }

            if (params.isRollbackResistant()) {
                importArgs.add(KeyStore2ParameterUtils.makeBool(
                        KeymasterDefs.KM_TAG_ROLLBACK_RESISTANT
                ));
            }
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new KeyStoreException(e);
        }
+20 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.locksettings;

import android.security.AndroidKeyStoreMaintenance;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
@@ -210,10 +211,26 @@ public class SyntheticPasswordCrypto {
                        .setBoundToSpecificSecureUserId(sid)
                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
            }
            final KeyProtection protNonRollbackResistant = builder.build();
            builder.setRollbackResistant(true);
            final KeyProtection protRollbackResistant = builder.build();
            final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(keyStoreKey);
            try {
                keyStore.setEntry(keyAlias, entry, protRollbackResistant);
                Slog.i(TAG, "Using rollback-resistant key");
            } catch (KeyStoreException e) {
                if (!(e.getCause() instanceof android.security.KeyStoreException)) {
                    throw e;
                }
                int errorCode = ((android.security.KeyStoreException) e.getCause()).getErrorCode();
                if (errorCode != KeymasterDefs.KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE) {
                    throw e;
                }
                Slog.w(TAG, "Rollback-resistant keys unavailable.  Falling back to "
                        + "non-rollback-resistant key");
                keyStore.setEntry(keyAlias, entry, protNonRollbackResistant);
            }

            keyStore.setEntry(keyAlias,
                    new KeyStore.SecretKeyEntry(keyStoreKey),
                    builder.build());
            byte[] intermediate = encrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, data);
            return encrypt(keyStoreKey, intermediate);
        } catch (CertificateException | IOException | BadPaddingException