Merge changes I05f3b7e5,Ifcfd0b8f

* changes:
  Request rollback resistance for SP protector keys
  AndroidKeyStore: support platform use of rollback-resistant keys
This commit is contained in:
Eric Biggers
2022-07-27 17:34:07 +00:00
committed by Android (Google) Code Review
3 changed files with 59 additions and 5 deletions

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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