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

Commit e0c8ad86 authored by Eran Messeri's avatar Eran Messeri
Browse files

MGF1 Digest setter: Handle case of flag off

In case the MGF1 Digest setter flag is turned off (that is, it is not
possible to specify MGF1 Digests using the new API introduced), then the
old behaviour has to take place.

The old behaviour was to set all primary digests specified, as MGF1 Digests.
This behaviour has been added when the flag isn't set.

Bug: 308378912
Bug: 308069562
Test: atest CtsKeystoreTestCases:android.keystore.cts.CipherTest#testKatBasicWithDifferentProviders CtsKeystoreWycheproofTestCases:RsaOaepTest
Change-Id: I5d4541ce952e1bad7c8fdd55a00176274b0b66f3
parent 3c95438e
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -39578,7 +39578,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();
@@ -39586,7 +39586,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();
@@ -39618,7 +39618,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);
@@ -39723,14 +39723,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();
@@ -39752,7 +39752,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);
+7 −0
Original line number Diff line number Diff line
@@ -7,6 +7,13 @@ flag {
    bug: "285185747"
}

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"
+3 −3
Original line number Diff line number Diff line
@@ -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;
+3 −3
Original line number Diff line number Diff line
@@ -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;
+17 −0
Original line number Diff line number Diff line
@@ -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 (!Flags.mgf1DigestSetter()) {
                    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) -> {
Loading