diff options
author | Eran Messeri <eranm@google.com> | 2023-12-07 16:21:40 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-12-07 16:21:40 +0000 |
commit | a20e3abb31408d97c6d68ccdcbc8dde6656c51ee (patch) | |
tree | 07bf28bd5b7e3c782944ea3e710d97754cf230d8 | |
parent | 67280cbad13c0f04f29336b4ec239f6192d84a77 (diff) | |
parent | 9fa406307161c0a648422caa97cf1d253a25caf0 (diff) | |
download | base-a20e3abb31408d97c6d68ccdcbc8dde6656c51ee.tar.gz |
Merge "Revert^2 "MGF1 Digest setter: Handle case of flag off"" into main am: 9fa4063071
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2854787
Change-Id: Ib7499cf79580cbac70e0cef4eb893ac5acd1e3d9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
6 files changed, 76 insertions, 12 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index b44ff6c8e0ea..c600df19a379 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39579,7 +39579,7 @@ package android.security.keystore { method @Nullable public java.util.Date getKeyValidityStart(); method @NonNull public String getKeystoreAlias(); method public int getMaxUsageCount(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); @@ -39587,7 +39587,7 @@ package android.security.keystore { method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified(); method public boolean isRandomizedEncryptionRequired(); method public boolean isStrongBoxBacked(); method public boolean isUnlockedDeviceRequired(); @@ -39619,7 +39619,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMaxUsageCount(int); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean); @@ -39724,14 +39724,14 @@ package android.security.keystore { method @Nullable public java.util.Date getKeyValidityForOriginationEnd(); method @Nullable public java.util.Date getKeyValidityStart(); method public int getMaxUsageCount(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUnlockedDeviceRequired(); method public boolean isUserAuthenticationRequired(); @@ -39753,7 +39753,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date); method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date); method @NonNull public android.security.keystore.KeyProtection.Builder setMaxUsageCount(int); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...); method @NonNull public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean); diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index ef1d682ee786..17f750410316 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -15,6 +15,13 @@ flag { } flag { + name: "mgf1_digest_setter" + namespace: "hardware_backed_security" + description: "Feature flag for mgf1 digest setter in key generation and import parameters." + bug: "308378912" +} + +flag { name: "fix_unlocked_device_required_keys_v2" namespace: "hardware_backed_security" description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys" diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 231fa4837441..4982f3732089 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -618,7 +618,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @see #isMgf1DigestsSpecified() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); @@ -633,7 +633,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @see #getMgf1Digests() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } @@ -1292,7 +1292,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public Builder setMgf1Digests(@NonNull @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index c1e3bab5d37c..7b6b2d142f95 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -401,7 +401,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * @see #isMgf1DigestsSpecified() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); @@ -416,7 +416,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * @see #getMgf1Digests() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } @@ -799,7 +799,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index ed4b485f3927..9c05a3a768a0 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -28,6 +28,7 @@ import android.hardware.security.keymint.SecurityLevel; import android.hardware.security.keymint.Tag; import android.os.Build; import android.os.StrictMode; +import android.security.Flags; import android.security.KeyPairGeneratorSpec; import android.security.KeyStore2; import android.security.KeyStoreException; @@ -853,6 +854,22 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mgf1Digest )); }); + + /* If the MGF1 Digest setter is not set, fall back to the previous behaviour: + * Add, as MGF1 Digest function, all the primary digests. + * Avoid adding the default MGF1 digest as it will have been included in the + * mKeymasterMgf1Digests field. + */ + if (!getMgf1DigestSetterFlag()) { + final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster( + DEFAULT_MGF1_DIGEST); + ArrayUtils.forEach(mKeymasterDigests, (digest) -> { + if (digest != defaultMgf1Digest) { + params.add(KeyStore2ParameterUtils.makeEnum( + KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest)); + } + }); + } } }); ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> { @@ -928,6 +945,16 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato return params; } + private static boolean getMgf1DigestSetterFlag() { + try { + return Flags.mgf1DigestSetter(); + } catch (SecurityException e) { + Log.w(TAG, "Cannot read MGF1 Digest setter flag value", e); + return false; + } + } + + private void addAlgorithmSpecificParameters(List<KeyParameter> params) { switch (mKeymasterAlgorithm) { case KeymasterDefs.KM_ALGORITHM_RSA: diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index ddbd93e458fd..2d8c5a380c6b 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -25,6 +25,7 @@ import android.hardware.security.keymint.HardwareAuthenticatorType; import android.hardware.security.keymint.KeyParameter; import android.hardware.security.keymint.SecurityLevel; import android.os.StrictMode; +import android.security.Flags; import android.security.GateKeeper; import android.security.KeyStore2; import android.security.KeyStoreParameter; @@ -256,6 +257,15 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } } + private static boolean getMgf1DigestSetterFlag() { + try { + return Flags.mgf1DigestSetter(); + } catch (SecurityException e) { + Log.w(NAME, "Cannot read MGF1 Digest setter flag value", e); + return false; + } + } + @Override public Date engineGetCreationDate(String alias) { KeyEntryResponse response = getKeyMetadata(alias); @@ -537,11 +547,31 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { /* Because of default MGF1 digest is SHA-1. It has to be added in Key * characteristics. Otherwise, crypto operations will fail with Incompatible * MGF1 digest. + * If the MGF1 Digest setter flag isn't set, then the condition in the + * if clause above must be false (cannot have MGF1 digests specified if the + * flag was off). In that case, in addition to adding the default MGF1 + * digest, we have to add all the other digests as MGF1 Digests. + * */ importArgs.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST) )); + if (!getMgf1DigestSetterFlag()) { + final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster( + DEFAULT_MGF1_DIGEST); + for (String digest : spec.getDigests()) { + int digestToAddAsMgf1Digest = KeyProperties.Digest.toKeymaster( + digest); + // Do not add the default MGF1 digest as it has been added above. + if (digestToAddAsMgf1Digest != defaultMgf1Digest) { + importArgs.add(KeyStore2ParameterUtils.makeEnum( + KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, + digestToAddAsMgf1Digest + )); + } + } + } } } } |