diff options
author | Alex Klyubin <klyubin@google.com> | 2015-04-08 14:15:57 -0700 |
---|---|---|
committer | Alex Klyubin <klyubin@google.com> | 2015-04-08 14:17:21 -0700 |
commit | 70376a77280551791dae62586a6bb0c77ed9429a (patch) | |
tree | f5ad15a4e33015a0b7bf7b83668569dd7cb7e8b1 /keystore | |
parent | c0d6b7cb752b50ed37197e15cc6f305a0038e61b (diff) | |
download | frameworks_base-70376a77280551791dae62586a6bb0c77ed9429a.zip frameworks_base-70376a77280551791dae62586a6bb0c77ed9429a.tar.gz frameworks_base-70376a77280551791dae62586a6bb0c77ed9429a.tar.bz2 |
Add more digests to AndroidKeyStore API.
This adds MD5, SHA-1, SHA-224, SHA-384, and SHA-512. SHA-256 was
already there.
MD5 is not exposed for HMAC on purpose, because MD5 has been
deprecated for years.
Bug: 18088752
Change-Id: I4df3d3f6cf10805c7910a1bdb577a91c85055945
Diffstat (limited to 'keystore')
4 files changed, 190 insertions, 23 deletions
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java index a59927d..635b2fa 100644 --- a/keystore/java/android/security/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/AndroidKeyStoreProvider.java @@ -49,14 +49,25 @@ public class AndroidKeyStoreProvider extends Provider { // javax.crypto.KeyGenerator put("KeyGenerator.AES", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$AES"); + put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA1"); + put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA224"); put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA256"); + put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA384"); + put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA512"); // java.security.SecretKeyFactory - put("SecretKeyFactory.AES", PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); - put("SecretKeyFactory.HmacSHA256", PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); + putSecretKeyFactoryImpl("AES"); + putSecretKeyFactoryImpl("HmacSHA1"); + putSecretKeyFactoryImpl("HmacSHA224"); + putSecretKeyFactoryImpl("HmacSHA256"); + putSecretKeyFactoryImpl("HmacSHA384"); + putSecretKeyFactoryImpl("HmacSHA512"); // javax.crypto.Mac + putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224"); putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256"); + putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384"); + putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512"); // javax.crypto.Cipher putSymmetricCipherImpl("AES/ECB/NoPadding", @@ -73,6 +84,10 @@ public class AndroidKeyStoreProvider extends Provider { PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding"); } + private void putSecretKeyFactoryImpl(String algorithm) { + put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); + } + private void putMacImpl(String algorithm, String implClass) { put("Mac." + algorithm, implClass); put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME); diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java index a5864a4..f69e7d1 100644 --- a/keystore/java/android/security/KeyStoreHmacSpi.java +++ b/keystore/java/android/security/KeyStoreHmacSpi.java @@ -35,9 +35,33 @@ import javax.crypto.MacSpi; */ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation { + public static class HmacSHA1 extends KeyStoreHmacSpi { + public HmacSHA1() { + super(KeyStoreKeyConstraints.Digest.SHA1); + } + } + + public static class HmacSHA224 extends KeyStoreHmacSpi { + public HmacSHA224() { + super(KeyStoreKeyConstraints.Digest.SHA224); + } + } + public static class HmacSHA256 extends KeyStoreHmacSpi { public HmacSHA256() { - super(KeyStoreKeyConstraints.Digest.SHA256, 256 / 8); + super(KeyStoreKeyConstraints.Digest.SHA256); + } + } + + public static class HmacSHA384 extends KeyStoreHmacSpi { + public HmacSHA384() { + super(KeyStoreKeyConstraints.Digest.SHA384); + } + } + + public static class HmacSHA512 extends KeyStoreHmacSpi { + public HmacSHA512() { + super(KeyStoreKeyConstraints.Digest.SHA512); } } @@ -52,9 +76,9 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp private IBinder mOperationToken; private Long mOperationHandle; - protected KeyStoreHmacSpi(@KeyStoreKeyConstraints.DigestEnum int digest, int macSizeBytes) { + protected KeyStoreHmacSpi(@KeyStoreKeyConstraints.DigestEnum int digest) { mDigest = digest; - mMacSizeBytes = macSizeBytes; + mMacSizeBytes = KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest); } @Override diff --git a/keystore/java/android/security/KeyStoreKeyConstraints.java b/keystore/java/android/security/KeyStoreKeyConstraints.java index 202e38d..9321302 100644 --- a/keystore/java/android/security/KeyStoreKeyConstraints.java +++ b/keystore/java/android/security/KeyStoreKeyConstraints.java @@ -327,7 +327,15 @@ public abstract class KeyStoreKeyConstraints { @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, - value = {Digest.NONE, Digest.SHA256}) + value = { + Digest.NONE, + Digest.MD5, + Digest.SHA1, + Digest.SHA224, + Digest.SHA256, + Digest.SHA384, + Digest.SHA512, + }) public @interface DigestEnum {} /** @@ -343,9 +351,34 @@ public abstract class KeyStoreKeyConstraints { public static final int NONE = 1 << 0; /** - * SHA-256 digest. + * MD5 digest. */ - public static final int SHA256 = 1 << 1; + public static final int MD5 = 1 << 1; + + /** + * SHA-1 digest. + */ + public static final int SHA1 = 1 << 2; + + /** + * SHA-2 224 (aka SHA-224) digest. + */ + public static final int SHA224 = 1 << 3; + + /** + * SHA-2 256 (aka SHA-256) digest. + */ + public static final int SHA256 = 1 << 4; + + /** + * SHA-2 384 (aka SHA-384) digest. + */ + public static final int SHA384 = 1 << 5; + + /** + * SHA-2 512 (aka SHA-512) digest. + */ + public static final int SHA512 = 1 << 6; /** * @hide @@ -354,8 +387,18 @@ public abstract class KeyStoreKeyConstraints { switch (digest) { case NONE: return "NONE"; + case MD5: + return "MD5"; + case SHA1: + return "SHA-1"; + case SHA224: + return "SHA-224"; case SHA256: - return "SHA256"; + return "SHA-256"; + case SHA384: + return "SHA-384"; + case SHA512: + return "SHA-512"; default: throw new IllegalArgumentException("Unknown digest: " + digest); } @@ -364,13 +407,19 @@ public abstract class KeyStoreKeyConstraints { /** * @hide */ - public static String[] allToString(@DigestEnum int digests) { - int[] values = getSetFlags(digests); - String[] result = new String[values.length]; - for (int i = 0; i < values.length; i++) { - result[i] = toString(values[i]); + public static String allToString(@DigestEnum int digests) { + StringBuilder result = new StringBuilder("["); + boolean firstValue = true; + for (@DigestEnum int digest : getSetFlags(digests)) { + if (firstValue) { + firstValue = false; + } else { + result.append(", "); + } + result.append(toString(digest)); } - return result; + result.append(']'); + return result.toString(); } /** @@ -380,8 +429,18 @@ public abstract class KeyStoreKeyConstraints { switch (digest) { case NONE: return KeymasterDefs.KM_DIGEST_NONE; + case MD5: + return KeymasterDefs.KM_DIGEST_MD5; + case SHA1: + return KeymasterDefs.KM_DIGEST_SHA1; + case SHA224: + return KeymasterDefs.KM_DIGEST_SHA_2_224; case SHA256: return KeymasterDefs.KM_DIGEST_SHA_2_256; + case SHA384: + return KeymasterDefs.KM_DIGEST_SHA_2_384; + case SHA512: + return KeymasterDefs.KM_DIGEST_SHA_2_512; default: throw new IllegalArgumentException("Unknown digest: " + digest); } @@ -394,8 +453,18 @@ public abstract class KeyStoreKeyConstraints { switch (digest) { case KeymasterDefs.KM_DIGEST_NONE: return NONE; + case KeymasterDefs.KM_DIGEST_MD5: + return MD5; + case KeymasterDefs.KM_DIGEST_SHA1: + return SHA1; + case KeymasterDefs.KM_DIGEST_SHA_2_224: + return SHA224; case KeymasterDefs.KM_DIGEST_SHA_2_256: return SHA256; + case KeymasterDefs.KM_DIGEST_SHA_2_384: + return SHA384; + case KeymasterDefs.KM_DIGEST_SHA_2_512: + return SHA512; default: throw new IllegalArgumentException("Unknown digest: " + digest); } @@ -429,11 +498,21 @@ public abstract class KeyStoreKeyConstraints { public static @DigestEnum Integer fromJCASecretKeyAlgorithm(String algorithm) { String algorithmLower = algorithm.toLowerCase(Locale.US); if (algorithmLower.startsWith("hmac")) { - if ("hmacsha256".equals(algorithmLower)) { + String digestLower = algorithmLower.substring("hmac".length()); + if ("md5".equals(digestLower)) { + return MD5; + } else if ("sha1".equals(digestLower)) { + return SHA1; + } else if ("sha224".equals(digestLower)) { + return SHA224; + } else if ("sha256".equals(digestLower)) { return SHA256; + } else if ("sha384".equals(digestLower)) { + return SHA384; + } else if ("sha512".equals(digestLower)) { + return SHA512; } else { - throw new IllegalArgumentException("Unsupported digest: " - + algorithmLower.substring("hmac".length())); + throw new IllegalArgumentException("Unsupported digest: " + digestLower); } } else { return null; @@ -447,8 +526,18 @@ public abstract class KeyStoreKeyConstraints { switch (digest) { case NONE: return "NONE"; + case MD5: + return "MD5"; + case SHA1: + return "SHA1"; + case SHA224: + return "SHA224"; case SHA256: return "SHA256"; + case SHA384: + return "SHA384"; + case SHA512: + return "SHA512"; default: throw new IllegalArgumentException("Unknown digest: " + digest); } @@ -461,8 +550,18 @@ public abstract class KeyStoreKeyConstraints { switch (digest) { case NONE: return null; + case MD5: + return 128 / 8; + case SHA1: + return 160 / 8; + case SHA224: + return 224 / 8; case SHA256: return 256 / 8; + case SHA384: + return 384 / 8; + case SHA512: + return 512 / 8; default: throw new IllegalArgumentException("Unknown digest: " + digest); } diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java index 09499d0..5be8c39 100644 --- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java @@ -41,12 +41,41 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } - public static class HmacSHA256 extends KeyStoreKeyGeneratorSpi { - public HmacSHA256() { + protected static abstract class HmacBase extends KeyStoreKeyGeneratorSpi { + protected HmacBase(@KeyStoreKeyConstraints.DigestEnum int digest) { super(KeyStoreKeyConstraints.Algorithm.HMAC, - KeyStoreKeyConstraints.Digest.SHA256, - KeyStoreKeyConstraints.Digest.getOutputSizeBytes( - KeyStoreKeyConstraints.Digest.SHA256) * 8); + digest, + KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest) * 8); + } + } + + public static class HmacSHA1 extends HmacBase { + public HmacSHA1() { + super(KeyStoreKeyConstraints.Digest.SHA1); + } + } + + public static class HmacSHA224 extends HmacBase { + public HmacSHA224() { + super(KeyStoreKeyConstraints.Digest.SHA224); + } + } + + public static class HmacSHA256 extends HmacBase { + public HmacSHA256() { + super(KeyStoreKeyConstraints.Digest.SHA256); + } + } + + public static class HmacSHA384 extends HmacBase { + public HmacSHA384() { + super(KeyStoreKeyConstraints.Digest.SHA384); + } + } + + public static class HmacSHA512 extends HmacBase { + public HmacSHA512() { + super(KeyStoreKeyConstraints.Digest.SHA512); } } |