Loading core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -37935,6 +37935,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 public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); Loading @@ -37942,6 +37943,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 public boolean isRandomizedEncryptionRequired(); method public boolean isStrongBoxBacked(); method public boolean isUnlockedDeviceRequired(); Loading Loading @@ -37973,6 +37975,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(@Nullable 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); Loading Loading @@ -38077,12 +38080,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 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 public boolean isRandomizedEncryptionRequired(); method public boolean isUnlockedDeviceRequired(); method public boolean isUserAuthenticationRequired(); Loading @@ -38104,6 +38109,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 @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); keystore/java/android/security/keystore/KeyGenParameterSpec.java +74 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.security.keystore; import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -34,7 +35,10 @@ import java.security.KeyPairGenerator; import java.security.Signature; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; Loading Loading @@ -300,6 +304,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final Date mKeyValidityForConsumptionEnd; private final @KeyProperties.PurposeEnum int mPurposes; private final @KeyProperties.DigestEnum String[] mDigests; private final @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests; private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private final @KeyProperties.BlockModeEnum String[] mBlockModes; Loading Loading @@ -343,6 +348,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu Date keyValidityForConsumptionEnd, @KeyProperties.PurposeEnum int purposes, @KeyProperties.DigestEnum String[] digests, @KeyProperties.DigestEnum Set<String> mgf1Digests, @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.BlockModeEnum String[] blockModes, Loading Loading @@ -401,6 +407,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); mPurposes = purposes; mDigests = ArrayUtils.cloneIfNotEmpty(digests); // No need to copy the input parameter because the Builder class passes in an immutable // collection. mMgf1Digests = mgf1Digests != null ? mgf1Digests : Collections.emptySet(); mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); Loading Loading @@ -562,7 +571,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu /** * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the * key can be used or {@code null} if not specified. * key can be used. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * Loading @@ -589,6 +598,40 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return mDigests != null; } /** * Returns the set of digests that can be used by the MGF1 mask generation function * (e.g., {@code SHA-256}, {@code SHA-384}) with the key. Useful with the {@code RSA-OAEP} * scheme. * If not explicitly specified during key generation, the default {@code SHA-1} digest is * used and may be specified when using the key. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * * @throws IllegalStateException if this set has not been specified. * * @see #isMgf1DigestsSpecified() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); } return new HashSet(mMgf1Digests); } /** * Returns {@code true} if the set of digests for the MGF1 mask generation function, * with which the key can be used, has been specified. Useful with the {@code RSA-OAEP} scheme. * * @see #getMgf1Digests() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } /** * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding}, * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when Loading Loading @@ -899,6 +942,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private Date mKeyValidityForOriginationEnd; private Date mKeyValidityForConsumptionEnd; private @KeyProperties.DigestEnum String[] mDigests; private @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests = Collections.emptySet(); private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private @KeyProperties.BlockModeEnum String[] mBlockModes; Loading Loading @@ -968,6 +1013,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu if (sourceSpec.isDigestsSpecified()) { mDigests = sourceSpec.getDigests(); } if (sourceSpec.isMgf1DigestsSpecified()) { mMgf1Digests = sourceSpec.getMgf1Digests(); } mEncryptionPaddings = sourceSpec.getEncryptionPaddings(); mSignaturePaddings = sourceSpec.getSignaturePaddings(); mBlockModes = sourceSpec.getBlockModes(); Loading Loading @@ -1213,6 +1261,30 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * Sets the set of hash functions (e.g., {@code SHA-256}, {@code SHA-384}) which could be * used by the mask generation function MGF1 (which is used for certain operations with * the key). Attempts to use the key with any other digest for the mask generation * function will be rejected. * * <p>This can only be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a mask generation * function (MGF1) with a digest. * The default digest for MGF1 is {@code SHA-1}, which will be specified during key creation * time if no digests have been explicitly provided. * When using the key, the caller may not specify any digests that were not provided during * key creation time. The caller may specify the default digest, {@code SHA-1}, if no * digests were explicitly provided during key creation (but it is not necessary to do so). * * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; } /** * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding}, * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when Loading Loading @@ -1745,6 +1817,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mKeyValidityForConsumptionEnd, mPurposes, mDigests, mMgf1Digests, mEncryptionPaddings, mSignaturePaddings, mBlockModes, Loading keystore/java/android/security/keystore/KeyProtection.java +68 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.security.keystore; import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -30,7 +31,10 @@ import java.security.Key; import java.security.KeyStore.ProtectionParameter; import java.security.Signature; import java.security.cert.Certificate; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.Mac; Loading Loading @@ -223,6 +227,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private final @KeyProperties.DigestEnum String[] mDigests; private final @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests; private final @KeyProperties.BlockModeEnum String[] mBlockModes; private final boolean mRandomizedEncryptionRequired; private final boolean mUserAuthenticationRequired; Loading @@ -246,6 +251,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.DigestEnum String[] digests, @KeyProperties.DigestEnum Set<String> mgf1Digests, @KeyProperties.BlockModeEnum String[] blockModes, boolean randomizedEncryptionRequired, boolean userAuthenticationRequired, Loading @@ -269,6 +275,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); mDigests = ArrayUtils.cloneIfNotEmpty(digests); mMgf1Digests = mgf1Digests; mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); mRandomizedEncryptionRequired = randomizedEncryptionRequired; mUserAuthenticationRequired = userAuthenticationRequired; Loading Loading @@ -377,6 +384,40 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { return mDigests != null; } /** * Returns the set of digests that can be used by the MGF1 mask generation function * (e.g., {@code SHA-256}, {@code SHA-384}) with the key. Useful with the {@code RSA-OAEP} * scheme. * If not explicitly specified during key generation, the default {@code SHA-1} digest is * used and may be specified. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * * @throws IllegalStateException if this set has not been specified. * * @see #isMgf1DigestsSpecified() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); } return new HashSet(mMgf1Digests); } /** * Returns {@code true} if the set of digests for the MGF1 mask generation function, * with which the key can be used, has been specified. Useful with the {@code RSA-OAEP} scheme. * * @see #getMgf1Digests() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } /** * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used * when encrypting/decrypting. Attempts to use the key with any other block modes will be Loading Loading @@ -574,6 +615,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private @KeyProperties.DigestEnum String[] mDigests; private @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests = Collections.emptySet(); private @KeyProperties.BlockModeEnum String[] mBlockModes; private boolean mRandomizedEncryptionRequired = true; private boolean mUserAuthenticationRequired; Loading Loading @@ -723,6 +766,30 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { return this; } /** * Sets the set of hash functions (e.g., {@code SHA-256}, {@code SHA-384}) which could be * used by the mask generation function MGF1 (which is used for certain operations with * the key). Attempts to use the key with any other digest for the mask generation * function will be rejected. * * <p>This can only be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a mask generation * function (MGF1) with a digest. * The default digest for MGF1 is {@code SHA-1}, which will be specified during key import * time if no digests have been explicitly provided. * When using the key, the caller may not specify any digests that were not provided during * key import time. The caller may specify the default digest, {@code SHA-1}, if no * digests were explicitly provided during key import (but it is not necessary to do so). * * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; } /** * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be * used when encrypting/decrypting. Attempts to use the key with any other block modes will Loading Loading @@ -1111,6 +1178,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mEncryptionPaddings, mSignaturePaddings, mDigests, mMgf1Digests, mBlockModes, mRandomizedEncryptionRequired, mUserAuthenticationRequired, Loading keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +11 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,11 @@ import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; Loading Loading @@ -91,6 +95,11 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { } else { out.writeStringArray(null); } if (mSpec.isMgf1DigestsSpecified()) { out.writeStringList(List.copyOf(mSpec.getMgf1Digests())); } else { out.writeStringList(null); } out.writeStringArray(mSpec.getEncryptionPaddings()); out.writeStringArray(mSpec.getSignaturePaddings()); out.writeStringArray(mSpec.getBlockModes()); Loading Loading @@ -152,6 +161,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final Date keyValidityForOriginationEnd = readDateOrNull(in); final Date keyValidityForConsumptionEnd = readDateOrNull(in); final String[] digests = in.createStringArray(); final ArrayList<String> mgf1Digests = in.createStringArrayList(); final String[] encryptionPaddings = in.createStringArray(); final String[] signaturePaddings = in.createStringArray(); final String[] blockModes = in.createStringArray(); Loading Loading @@ -189,6 +199,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { keyValidityForConsumptionEnd, purposes, digests, mgf1Digests != null ? Set.copyOf(mgf1Digests) : Collections.emptySet(), encryptionPaddings, signaturePaddings, blockModes, Loading keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.StrictMode; import android.security.KeyStoreException; import android.security.KeyStoreOperation; import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyProperties; import android.security.keystore.KeyStoreCryptoOperation; import android.system.keystore2.Authorization; Loading Loading @@ -71,7 +72,7 @@ import javax.crypto.spec.SecretKeySpec; */ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation { private static final String TAG = "AndroidKeyStoreCipherSpiBase"; public static final String DEFAULT_MGF1_DIGEST = "SHA-1"; public static final String DEFAULT_MGF1_DIGEST = KeyProperties.DIGEST_SHA1; // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // doFinal finishes. Loading Loading
core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -37935,6 +37935,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 public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); Loading @@ -37942,6 +37943,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 public boolean isRandomizedEncryptionRequired(); method public boolean isStrongBoxBacked(); method public boolean isUnlockedDeviceRequired(); Loading Loading @@ -37973,6 +37975,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(@Nullable 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); Loading Loading @@ -38077,12 +38080,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 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 public boolean isRandomizedEncryptionRequired(); method public boolean isUnlockedDeviceRequired(); method public boolean isUserAuthenticationRequired(); Loading @@ -38104,6 +38109,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 @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);
keystore/java/android/security/keystore/KeyGenParameterSpec.java +74 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.security.keystore; import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -34,7 +35,10 @@ import java.security.KeyPairGenerator; import java.security.Signature; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; Loading Loading @@ -300,6 +304,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final Date mKeyValidityForConsumptionEnd; private final @KeyProperties.PurposeEnum int mPurposes; private final @KeyProperties.DigestEnum String[] mDigests; private final @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests; private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private final @KeyProperties.BlockModeEnum String[] mBlockModes; Loading Loading @@ -343,6 +348,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu Date keyValidityForConsumptionEnd, @KeyProperties.PurposeEnum int purposes, @KeyProperties.DigestEnum String[] digests, @KeyProperties.DigestEnum Set<String> mgf1Digests, @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.BlockModeEnum String[] blockModes, Loading Loading @@ -401,6 +407,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); mPurposes = purposes; mDigests = ArrayUtils.cloneIfNotEmpty(digests); // No need to copy the input parameter because the Builder class passes in an immutable // collection. mMgf1Digests = mgf1Digests != null ? mgf1Digests : Collections.emptySet(); mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); Loading Loading @@ -562,7 +571,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu /** * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the * key can be used or {@code null} if not specified. * key can be used. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * Loading @@ -589,6 +598,40 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return mDigests != null; } /** * Returns the set of digests that can be used by the MGF1 mask generation function * (e.g., {@code SHA-256}, {@code SHA-384}) with the key. Useful with the {@code RSA-OAEP} * scheme. * If not explicitly specified during key generation, the default {@code SHA-1} digest is * used and may be specified when using the key. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * * @throws IllegalStateException if this set has not been specified. * * @see #isMgf1DigestsSpecified() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); } return new HashSet(mMgf1Digests); } /** * Returns {@code true} if the set of digests for the MGF1 mask generation function, * with which the key can be used, has been specified. Useful with the {@code RSA-OAEP} scheme. * * @see #getMgf1Digests() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } /** * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding}, * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when Loading Loading @@ -899,6 +942,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private Date mKeyValidityForOriginationEnd; private Date mKeyValidityForConsumptionEnd; private @KeyProperties.DigestEnum String[] mDigests; private @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests = Collections.emptySet(); private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private @KeyProperties.BlockModeEnum String[] mBlockModes; Loading Loading @@ -968,6 +1013,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu if (sourceSpec.isDigestsSpecified()) { mDigests = sourceSpec.getDigests(); } if (sourceSpec.isMgf1DigestsSpecified()) { mMgf1Digests = sourceSpec.getMgf1Digests(); } mEncryptionPaddings = sourceSpec.getEncryptionPaddings(); mSignaturePaddings = sourceSpec.getSignaturePaddings(); mBlockModes = sourceSpec.getBlockModes(); Loading Loading @@ -1213,6 +1261,30 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * Sets the set of hash functions (e.g., {@code SHA-256}, {@code SHA-384}) which could be * used by the mask generation function MGF1 (which is used for certain operations with * the key). Attempts to use the key with any other digest for the mask generation * function will be rejected. * * <p>This can only be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a mask generation * function (MGF1) with a digest. * The default digest for MGF1 is {@code SHA-1}, which will be specified during key creation * time if no digests have been explicitly provided. * When using the key, the caller may not specify any digests that were not provided during * key creation time. The caller may specify the default digest, {@code SHA-1}, if no * digests were explicitly provided during key creation (but it is not necessary to do so). * * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; } /** * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding}, * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when Loading Loading @@ -1745,6 +1817,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mKeyValidityForConsumptionEnd, mPurposes, mDigests, mMgf1Digests, mEncryptionPaddings, mSignaturePaddings, mBlockModes, Loading
keystore/java/android/security/keystore/KeyProtection.java +68 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.security.keystore; import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -30,7 +31,10 @@ import java.security.Key; import java.security.KeyStore.ProtectionParameter; import java.security.Signature; import java.security.cert.Certificate; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.Mac; Loading Loading @@ -223,6 +227,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private final @KeyProperties.DigestEnum String[] mDigests; private final @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests; private final @KeyProperties.BlockModeEnum String[] mBlockModes; private final boolean mRandomizedEncryptionRequired; private final boolean mUserAuthenticationRequired; Loading @@ -246,6 +251,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.DigestEnum String[] digests, @KeyProperties.DigestEnum Set<String> mgf1Digests, @KeyProperties.BlockModeEnum String[] blockModes, boolean randomizedEncryptionRequired, boolean userAuthenticationRequired, Loading @@ -269,6 +275,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); mDigests = ArrayUtils.cloneIfNotEmpty(digests); mMgf1Digests = mgf1Digests; mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); mRandomizedEncryptionRequired = randomizedEncryptionRequired; mUserAuthenticationRequired = userAuthenticationRequired; Loading Loading @@ -377,6 +384,40 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { return mDigests != null; } /** * Returns the set of digests that can be used by the MGF1 mask generation function * (e.g., {@code SHA-256}, {@code SHA-384}) with the key. Useful with the {@code RSA-OAEP} * scheme. * If not explicitly specified during key generation, the default {@code SHA-1} digest is * used and may be specified. * * <p>See {@link KeyProperties}.{@code DIGEST} constants. * * @throws IllegalStateException if this set has not been specified. * * @see #isMgf1DigestsSpecified() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); } return new HashSet(mMgf1Digests); } /** * Returns {@code true} if the set of digests for the MGF1 mask generation function, * with which the key can be used, has been specified. Useful with the {@code RSA-OAEP} scheme. * * @see #getMgf1Digests() */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } /** * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used * when encrypting/decrypting. Attempts to use the key with any other block modes will be Loading Loading @@ -574,6 +615,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; private @KeyProperties.DigestEnum String[] mDigests; private @NonNull @KeyProperties.DigestEnum Set<String> mMgf1Digests = Collections.emptySet(); private @KeyProperties.BlockModeEnum String[] mBlockModes; private boolean mRandomizedEncryptionRequired = true; private boolean mUserAuthenticationRequired; Loading Loading @@ -723,6 +766,30 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { return this; } /** * Sets the set of hash functions (e.g., {@code SHA-256}, {@code SHA-384}) which could be * used by the mask generation function MGF1 (which is used for certain operations with * the key). Attempts to use the key with any other digest for the mask generation * function will be rejected. * * <p>This can only be specified for signing/verification keys and RSA encryption/decryption * keys used with RSA OAEP padding scheme because these operations involve a mask generation * function (MGF1) with a digest. * The default digest for MGF1 is {@code SHA-1}, which will be specified during key import * time if no digests have been explicitly provided. * When using the key, the caller may not specify any digests that were not provided during * key import time. The caller may specify the default digest, {@code SHA-1}, if no * digests were explicitly provided during key import (but it is not necessary to do so). * * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; } /** * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be * used when encrypting/decrypting. Attempts to use the key with any other block modes will Loading Loading @@ -1111,6 +1178,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mEncryptionPaddings, mSignaturePaddings, mDigests, mMgf1Digests, mBlockModes, mRandomizedEncryptionRequired, mUserAuthenticationRequired, Loading
keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +11 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,11 @@ import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; Loading Loading @@ -91,6 +95,11 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { } else { out.writeStringArray(null); } if (mSpec.isMgf1DigestsSpecified()) { out.writeStringList(List.copyOf(mSpec.getMgf1Digests())); } else { out.writeStringList(null); } out.writeStringArray(mSpec.getEncryptionPaddings()); out.writeStringArray(mSpec.getSignaturePaddings()); out.writeStringArray(mSpec.getBlockModes()); Loading Loading @@ -152,6 +161,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final Date keyValidityForOriginationEnd = readDateOrNull(in); final Date keyValidityForConsumptionEnd = readDateOrNull(in); final String[] digests = in.createStringArray(); final ArrayList<String> mgf1Digests = in.createStringArrayList(); final String[] encryptionPaddings = in.createStringArray(); final String[] signaturePaddings = in.createStringArray(); final String[] blockModes = in.createStringArray(); Loading Loading @@ -189,6 +199,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { keyValidityForConsumptionEnd, purposes, digests, mgf1Digests != null ? Set.copyOf(mgf1Digests) : Collections.emptySet(), encryptionPaddings, signaturePaddings, blockModes, Loading
keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.StrictMode; import android.security.KeyStoreException; import android.security.KeyStoreOperation; import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyProperties; import android.security.keystore.KeyStoreCryptoOperation; import android.system.keystore2.Authorization; Loading Loading @@ -71,7 +72,7 @@ import javax.crypto.spec.SecretKeySpec; */ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation { private static final String TAG = "AndroidKeyStoreCipherSpiBase"; public static final String DEFAULT_MGF1_DIGEST = "SHA-1"; public static final String DEFAULT_MGF1_DIGEST = KeyProperties.DIGEST_SHA1; // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // doFinal finishes. Loading