AndroidKeyStore: support platform use of rollback-resistant keys

The keystore2 binder API supports rollback resistance when KeyMint
supports it, but until now this wasn't exposed to Java code that uses
AndroidKeyStore.  Add support for rollback-resistant keys to
KeyProtection and AndroidKeyStoreSpi.setSecretKeyEntry() so that
LockSettingsService can request it for SP protector keys.

This CL does *not* do any of the following:

- Add any non-hidden APIs.  KeyMint implementations only support a
  limited number of rollback-resistant keys; currently the available
  space is reserved for platform use only.  Note that other examples of
  "hidden", platform-only key properties are
  isCriticalToDeviceEncryption() and getBoundToSpecificSecureUserId().

- Support rollback resistance with keys directly generated by Keystore.
  This isn't currently needed.  Note that this would require changes
  KeyGenParameterSpec and AndroidKeyStoreKeyGeneratorSpi.

- Allow querying the rollback resistance property of keys.  This isn't
  currently needed.  Note that this would require changes to KeyInfo and
  AndroidKeyStoreSecretKeyFactorySpi.

Bug: 239632930
Test: see I05f3b7e5c139471febe5c266a39e3dc3bca4831f
Change-Id: Ifcfd0b8f1bf440ef1ac80a9ac2b0e9c7f62106dd
This commit is contained in:
Eric Biggers
2022-07-23 00:28:01 +00:00
parent cd671e384b
commit 34945b1fd2
2 changed files with 39 additions and 2 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);
}