Loading core/java/android/security/keymaster/KeymasterDefs.java +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ public final class KeymasterDefs { public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; public static final int KM_TAG_RSA_OAEP_MGF_DIGEST = Tag.RSA_OAEP_MGF_DIGEST; // KM_ENUM_REP | 203; public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400; public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = Loading keystore/java/android/security/keystore/KeyProperties.java +22 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import libcore.util.EmptyArray; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.MGF1ParameterSpec; import java.util.Collection; import java.util.Locale; Loading Loading @@ -675,6 +677,26 @@ public abstract class KeyProperties { } } /** * @hide */ @NonNull public static @DigestEnum AlgorithmParameterSpec fromKeymasterToMGF1ParameterSpec(int digest) { switch (digest) { default: case KeymasterDefs.KM_DIGEST_SHA1: return MGF1ParameterSpec.SHA1; case KeymasterDefs.KM_DIGEST_SHA_2_224: return MGF1ParameterSpec.SHA224; case KeymasterDefs.KM_DIGEST_SHA_2_256: return MGF1ParameterSpec.SHA256; case KeymasterDefs.KM_DIGEST_SHA_2_384: return MGF1ParameterSpec.SHA384; case KeymasterDefs.KM_DIGEST_SHA_2_512: return MGF1ParameterSpec.SHA512; } } @NonNull public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) { switch (digest) { Loading keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +9 −4 Original line number Diff line number Diff line Loading @@ -69,6 +69,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"; // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // doFinal finishes. Loading Loading @@ -133,24 +134,28 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-384", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else { mCipher.init(opmode, key, random); Loading keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +22 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.security.keystore2; import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; Loading Loading @@ -908,6 +910,26 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_PADDING, padding )); if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) { final boolean[] hasDefaultMgf1DigestBeenAdded = {false}; ArrayUtils.forEach(mKeymasterDigests, (digest) -> { params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest )); hasDefaultMgf1DigestBeenAdded[0] |= digest.equals(KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)); }); /* 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 (!hasDefaultMgf1DigestBeenAdded[0]) { params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST) )); } } }); ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> { params.add(KeyStore2ParameterUtils.makeEnum( Loading keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java +12 −12 Original line number Diff line number Diff line Loading @@ -161,10 +161,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase */ abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi { private static final String MGF_ALGORITGM_MGF1 = "MGF1"; private static final String MGF_ALGORITHM_MGF1 = "MGF1"; private int mKeymasterDigest = -1; private int mDigestOutputSizeBytes; private int mKeymasterMgf1Digest = KeymasterDefs.KM_DIGEST_SHA1; // Default MGF1 digest OAEPWithMGF1Padding(int keymasterDigest) { super(KeymasterDefs.KM_PAD_RSA_OAEP); Loading @@ -189,10 +190,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase + ". Only OAEPParameterSpec supported"); } OAEPParameterSpec spec = (OAEPParameterSpec) params; if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { if (!MGF_ALGORITHM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { throw new InvalidAlgorithmParameterException( "Unsupported MGF: " + spec.getMGFAlgorithm() + ". Only " + MGF_ALGORITGM_MGF1 + " supported"); + ". Only " + MGF_ALGORITHM_MGF1 + " supported"); } String jcaDigest = spec.getDigestAlgorithm(); int keymasterDigest; Loading Loading @@ -225,11 +226,6 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase } MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams; String mgf1JcaDigest = mgfSpec.getDigestAlgorithm(); if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) { throw new InvalidAlgorithmParameterException( "Unsupported MGF1 digest: " + mgf1JcaDigest + ". Only " + KeyProperties.DIGEST_SHA1 + " supported"); } PSource pSource = spec.getPSource(); if (!(pSource instanceof PSource.PSpecified)) { throw new InvalidAlgorithmParameterException( Loading @@ -244,6 +240,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported"); } mKeymasterDigest = keymasterDigest; mKeymasterMgf1Digest = KeyProperties.Digest.toKeymaster(mgf1JcaDigest); mDigestOutputSizeBytes = (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8; } Loading Loading @@ -274,8 +271,8 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase OAEPParameterSpec spec = new OAEPParameterSpec( KeyProperties.Digest.fromKeymaster(mKeymasterDigest), MGF_ALGORITGM_MGF1, MGF1ParameterSpec.SHA1, MGF_ALGORITHM_MGF1, KeyProperties.Digest.fromKeymasterToMGF1ParameterSpec(mKeymasterMgf1Digest), PSource.PSpecified.DEFAULT); try { AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP"); Loading @@ -298,6 +295,9 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest )); parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest )); } @Override Loading Loading
core/java/android/security/keymaster/KeymasterDefs.java +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ public final class KeymasterDefs { public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; public static final int KM_TAG_RSA_OAEP_MGF_DIGEST = Tag.RSA_OAEP_MGF_DIGEST; // KM_ENUM_REP | 203; public static final int KM_TAG_ACTIVE_DATETIME = Tag.ACTIVE_DATETIME; // KM_DATE | 400; public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = Loading
keystore/java/android/security/keystore/KeyProperties.java +22 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import libcore.util.EmptyArray; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.MGF1ParameterSpec; import java.util.Collection; import java.util.Locale; Loading Loading @@ -675,6 +677,26 @@ public abstract class KeyProperties { } } /** * @hide */ @NonNull public static @DigestEnum AlgorithmParameterSpec fromKeymasterToMGF1ParameterSpec(int digest) { switch (digest) { default: case KeymasterDefs.KM_DIGEST_SHA1: return MGF1ParameterSpec.SHA1; case KeymasterDefs.KM_DIGEST_SHA_2_224: return MGF1ParameterSpec.SHA224; case KeymasterDefs.KM_DIGEST_SHA_2_256: return MGF1ParameterSpec.SHA256; case KeymasterDefs.KM_DIGEST_SHA_2_384: return MGF1ParameterSpec.SHA384; case KeymasterDefs.KM_DIGEST_SHA_2_512: return MGF1ParameterSpec.SHA512; } } @NonNull public static @DigestEnum String fromKeymasterToSignatureAlgorithmDigest(int digest) { switch (digest) { Loading
keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java +9 −4 Original line number Diff line number Diff line Loading @@ -69,6 +69,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"; // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after // doFinal finishes. Loading Loading @@ -133,24 +134,28 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-384", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) { OAEPParameterSpec spec = new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT); new MGF1ParameterSpec(DEFAULT_MGF1_DIGEST), PSource.PSpecified.DEFAULT); mCipher.init(opmode, key, spec, random); } else { mCipher.init(opmode, key, random); Loading
keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +22 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.security.keystore2; import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MGF1_DIGEST; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; Loading Loading @@ -908,6 +910,26 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_PADDING, padding )); if (padding == KeymasterDefs.KM_PAD_RSA_OAEP) { final boolean[] hasDefaultMgf1DigestBeenAdded = {false}; ArrayUtils.forEach(mKeymasterDigests, (digest) -> { params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest )); hasDefaultMgf1DigestBeenAdded[0] |= digest.equals(KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)); }); /* 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 (!hasDefaultMgf1DigestBeenAdded[0]) { params.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST) )); } } }); ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> { params.add(KeyStore2ParameterUtils.makeEnum( Loading
keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java +12 −12 Original line number Diff line number Diff line Loading @@ -161,10 +161,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase */ abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi { private static final String MGF_ALGORITGM_MGF1 = "MGF1"; private static final String MGF_ALGORITHM_MGF1 = "MGF1"; private int mKeymasterDigest = -1; private int mDigestOutputSizeBytes; private int mKeymasterMgf1Digest = KeymasterDefs.KM_DIGEST_SHA1; // Default MGF1 digest OAEPWithMGF1Padding(int keymasterDigest) { super(KeymasterDefs.KM_PAD_RSA_OAEP); Loading @@ -189,10 +190,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase + ". Only OAEPParameterSpec supported"); } OAEPParameterSpec spec = (OAEPParameterSpec) params; if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { if (!MGF_ALGORITHM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { throw new InvalidAlgorithmParameterException( "Unsupported MGF: " + spec.getMGFAlgorithm() + ". Only " + MGF_ALGORITGM_MGF1 + " supported"); + ". Only " + MGF_ALGORITHM_MGF1 + " supported"); } String jcaDigest = spec.getDigestAlgorithm(); int keymasterDigest; Loading Loading @@ -225,11 +226,6 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase } MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams; String mgf1JcaDigest = mgfSpec.getDigestAlgorithm(); if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) { throw new InvalidAlgorithmParameterException( "Unsupported MGF1 digest: " + mgf1JcaDigest + ". Only " + KeyProperties.DIGEST_SHA1 + " supported"); } PSource pSource = spec.getPSource(); if (!(pSource instanceof PSource.PSpecified)) { throw new InvalidAlgorithmParameterException( Loading @@ -244,6 +240,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported"); } mKeymasterDigest = keymasterDigest; mKeymasterMgf1Digest = KeyProperties.Digest.toKeymaster(mgf1JcaDigest); mDigestOutputSizeBytes = (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8; } Loading Loading @@ -274,8 +271,8 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase OAEPParameterSpec spec = new OAEPParameterSpec( KeyProperties.Digest.fromKeymaster(mKeymasterDigest), MGF_ALGORITGM_MGF1, MGF1ParameterSpec.SHA1, MGF_ALGORITHM_MGF1, KeyProperties.Digest.fromKeymasterToMGF1ParameterSpec(mKeymasterMgf1Digest), PSource.PSpecified.DEFAULT); try { AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP"); Loading @@ -298,6 +295,9 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest )); parameters.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mKeymasterMgf1Digest )); } @Override Loading