am 1da3d7fc: Merge "Add more digests to AndroidKeyStore API."

* commit '1da3d7fcf33fd61f0143f8a410f0a77783fe1bfe':
  Add more digests to AndroidKeyStore API.
This commit is contained in:
Alex Klyubin
2015-04-09 00:32:38 +00:00
committed by Android Git Automerger
4 changed files with 190 additions and 23 deletions

View File

@@ -49,14 +49,25 @@ public class AndroidKeyStoreProvider extends Provider {
// javax.crypto.KeyGenerator // javax.crypto.KeyGenerator
put("KeyGenerator.AES", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$AES"); 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.HmacSHA256", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA256");
put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA384");
put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA512");
// java.security.SecretKeyFactory // java.security.SecretKeyFactory
put("SecretKeyFactory.AES", PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); putSecretKeyFactoryImpl("AES");
put("SecretKeyFactory.HmacSHA256", PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi"); putSecretKeyFactoryImpl("HmacSHA1");
putSecretKeyFactoryImpl("HmacSHA224");
putSecretKeyFactoryImpl("HmacSHA256");
putSecretKeyFactoryImpl("HmacSHA384");
putSecretKeyFactoryImpl("HmacSHA512");
// javax.crypto.Mac // javax.crypto.Mac
putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224");
putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256"); putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256");
putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384");
putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512");
// javax.crypto.Cipher // javax.crypto.Cipher
putSymmetricCipherImpl("AES/ECB/NoPadding", putSymmetricCipherImpl("AES/ECB/NoPadding",
@@ -73,6 +84,10 @@ public class AndroidKeyStoreProvider extends Provider {
PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding"); PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding");
} }
private void putSecretKeyFactoryImpl(String algorithm) {
put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi");
}
private void putMacImpl(String algorithm, String implClass) { private void putMacImpl(String algorithm, String implClass) {
put("Mac." + algorithm, implClass); put("Mac." + algorithm, implClass);
put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME); put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);

View File

@@ -35,9 +35,33 @@ import javax.crypto.MacSpi;
*/ */
public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation { 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 static class HmacSHA256 extends KeyStoreHmacSpi {
public HmacSHA256() { 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 IBinder mOperationToken;
private Long mOperationHandle; private Long mOperationHandle;
protected KeyStoreHmacSpi(@KeyStoreKeyConstraints.DigestEnum int digest, int macSizeBytes) { protected KeyStoreHmacSpi(@KeyStoreKeyConstraints.DigestEnum int digest) {
mDigest = digest; mDigest = digest;
mMacSizeBytes = macSizeBytes; mMacSizeBytes = KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest);
} }
@Override @Override

View File

@@ -327,7 +327,15 @@ public abstract class KeyStoreKeyConstraints {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, @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 {} public @interface DigestEnum {}
/** /**
@@ -343,9 +351,34 @@ public abstract class KeyStoreKeyConstraints {
public static final int NONE = 1 << 0; 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 * @hide
@@ -354,8 +387,18 @@ public abstract class KeyStoreKeyConstraints {
switch (digest) { switch (digest) {
case NONE: case NONE:
return "NONE"; return "NONE";
case MD5:
return "MD5";
case SHA1:
return "SHA-1";
case SHA224:
return "SHA-224";
case SHA256: case SHA256:
return "SHA256"; return "SHA-256";
case SHA384:
return "SHA-384";
case SHA512:
return "SHA-512";
default: default:
throw new IllegalArgumentException("Unknown digest: " + digest); throw new IllegalArgumentException("Unknown digest: " + digest);
} }
@@ -364,13 +407,19 @@ public abstract class KeyStoreKeyConstraints {
/** /**
* @hide * @hide
*/ */
public static String[] allToString(@DigestEnum int digests) { public static String allToString(@DigestEnum int digests) {
int[] values = getSetFlags(digests); StringBuilder result = new StringBuilder("[");
String[] result = new String[values.length]; boolean firstValue = true;
for (int i = 0; i < values.length; i++) { for (@DigestEnum int digest : getSetFlags(digests)) {
result[i] = toString(values[i]); 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) { switch (digest) {
case NONE: case NONE:
return KeymasterDefs.KM_DIGEST_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: case SHA256:
return KeymasterDefs.KM_DIGEST_SHA_2_256; 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: default:
throw new IllegalArgumentException("Unknown digest: " + digest); throw new IllegalArgumentException("Unknown digest: " + digest);
} }
@@ -394,8 +453,18 @@ public abstract class KeyStoreKeyConstraints {
switch (digest) { switch (digest) {
case KeymasterDefs.KM_DIGEST_NONE: case KeymasterDefs.KM_DIGEST_NONE:
return 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: case KeymasterDefs.KM_DIGEST_SHA_2_256:
return SHA256; return SHA256;
case KeymasterDefs.KM_DIGEST_SHA_2_384:
return SHA384;
case KeymasterDefs.KM_DIGEST_SHA_2_512:
return SHA512;
default: default:
throw new IllegalArgumentException("Unknown digest: " + digest); throw new IllegalArgumentException("Unknown digest: " + digest);
} }
@@ -429,11 +498,21 @@ public abstract class KeyStoreKeyConstraints {
public static @DigestEnum Integer fromJCASecretKeyAlgorithm(String algorithm) { public static @DigestEnum Integer fromJCASecretKeyAlgorithm(String algorithm) {
String algorithmLower = algorithm.toLowerCase(Locale.US); String algorithmLower = algorithm.toLowerCase(Locale.US);
if (algorithmLower.startsWith("hmac")) { 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; return SHA256;
} else if ("sha384".equals(digestLower)) {
return SHA384;
} else if ("sha512".equals(digestLower)) {
return SHA512;
} else { } else {
throw new IllegalArgumentException("Unsupported digest: " throw new IllegalArgumentException("Unsupported digest: " + digestLower);
+ algorithmLower.substring("hmac".length()));
} }
} else { } else {
return null; return null;
@@ -447,8 +526,18 @@ public abstract class KeyStoreKeyConstraints {
switch (digest) { switch (digest) {
case NONE: case NONE:
return "NONE"; return "NONE";
case MD5:
return "MD5";
case SHA1:
return "SHA1";
case SHA224:
return "SHA224";
case SHA256: case SHA256:
return "SHA256"; return "SHA256";
case SHA384:
return "SHA384";
case SHA512:
return "SHA512";
default: default:
throw new IllegalArgumentException("Unknown digest: " + digest); throw new IllegalArgumentException("Unknown digest: " + digest);
} }
@@ -461,8 +550,18 @@ public abstract class KeyStoreKeyConstraints {
switch (digest) { switch (digest) {
case NONE: case NONE:
return null; return null;
case MD5:
return 128 / 8;
case SHA1:
return 160 / 8;
case SHA224:
return 224 / 8;
case SHA256: case SHA256:
return 256 / 8; return 256 / 8;
case SHA384:
return 384 / 8;
case SHA512:
return 512 / 8;
default: default:
throw new IllegalArgumentException("Unknown digest: " + digest); throw new IllegalArgumentException("Unknown digest: " + digest);
} }

View File

@@ -41,12 +41,41 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
} }
} }
public static class HmacSHA256 extends KeyStoreKeyGeneratorSpi { protected static abstract class HmacBase extends KeyStoreKeyGeneratorSpi {
public HmacSHA256() { protected HmacBase(@KeyStoreKeyConstraints.DigestEnum int digest) {
super(KeyStoreKeyConstraints.Algorithm.HMAC, super(KeyStoreKeyConstraints.Algorithm.HMAC,
KeyStoreKeyConstraints.Digest.SHA256, digest,
KeyStoreKeyConstraints.Digest.getOutputSizeBytes( KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest) * 8);
KeyStoreKeyConstraints.Digest.SHA256) * 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);
} }
} }