Track Keymaster changes.
* MAC length is now specified as a parameters to the begin operation
instead of as a parameter at key generation/import time.
* KM_TAG_MAC_LENGTH is now in bits instead of in bytes.
Change-Id: I752fe232d11d3ac39a575a48948215d84ded8fb9
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index ed91d70..72cb062 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -486,16 +486,6 @@
}
}
args.addInts(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
- if (keymasterDigests.length > 0) {
- // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
- // This code will blow up if mode than one digest is specified.
- int digestOutputSizeBytes =
- KeymasterUtils.getDigestOutputSizeBytes(keymasterDigests[0]);
- if (digestOutputSizeBytes != -1) {
- // TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
- args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
- }
- }
if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
if (keymasterDigests.length == 0) {
throw new KeyStoreException("At least one digest algorithm must be specified"
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index 4590b9c..c52f61b 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -67,7 +67,7 @@
private final KeyStore mKeyStore = KeyStore.getInstance();
private final int mKeymasterDigest;
- private final int mMacSizeBytes;
+ private final int mMacSizeBits;
// Fields below are populated by engineInit and should be preserved after engineDoFinal.
private KeyStoreSecretKey mKey;
@@ -79,12 +79,12 @@
protected KeyStoreHmacSpi(int keymasterDigest) {
mKeymasterDigest = keymasterDigest;
- mMacSizeBytes = KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest);
+ mMacSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
}
@Override
protected int engineGetMacLength() {
- return mMacSizeBytes;
+ return (mMacSizeBits + 7) / 8;
}
@Override
@@ -158,14 +158,16 @@
KeymasterArguments keymasterArgs = new KeymasterArguments();
keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
+ KeymasterArguments keymasterOutputArgs = new KeymasterArguments();
OperationResult opResult = mKeyStore.begin(
mKey.getAlias(),
KeymasterDefs.KM_PURPOSE_SIGN,
true,
keymasterArgs,
- null,
- new KeymasterArguments());
+ null, // no additional entropy needed for HMAC because it's deterministic
+ keymasterOutputArgs);
if (opResult == null) {
throw new KeyStoreConnectException();
} else if ((opResult.resultCode != KeyStore.NO_ERROR)
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 20f6042..68b5751 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -45,7 +45,7 @@
protected HmacBase(int keymasterDigest) {
super(KeymasterDefs.KM_ALGORITHM_HMAC,
keymasterDigest,
- KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest) * 8);
+ KeymasterUtils.getDigestOutputSizeBits(keymasterDigest));
}
}
@@ -120,13 +120,6 @@
args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
if (mKeymasterDigest != -1) {
args.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- int digestOutputSizeBytes =
- KeymasterUtils.getDigestOutputSizeBytes(mKeymasterDigest);
- if (digestOutputSizeBytes != -1) {
- // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
- // TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
- args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
- }
}
if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
if (mKeymasterDigest == -1) {
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 3ccb588..aa44ecd 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -179,22 +179,22 @@
return result;
}
- public static int getDigestOutputSizeBytes(int keymasterDigest) {
+ public static int getDigestOutputSizeBits(int keymasterDigest) {
switch (keymasterDigest) {
case KeymasterDefs.KM_DIGEST_NONE:
return -1;
case KeymasterDefs.KM_DIGEST_MD5:
- return 128 / 8;
+ return 128;
case KeymasterDefs.KM_DIGEST_SHA1:
- return 160 / 8;
+ return 160;
case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return 224 / 8;
+ return 224;
case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return 256 / 8;
+ return 256;
case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return 384 / 8;
+ return 384;
case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return 512 / 8;
+ return 512;
default:
throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
}