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
This commit is contained in:
Rubin Xu
2019-12-24 13:35:02 +00:00
parent d69517ebf1
commit b3a13e1e2c
5 changed files with 45 additions and 6 deletions

View File

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

View File

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

View File

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

View File

@@ -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>() {

View File

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